Has anyone ever had a use for the __COUNTER__ pre-processor macro?

前端 未结 16 1382
有刺的猬
有刺的猬 2020-11-29 00:37

The __COUNTER__ symbol is provided by VC++ and GCC, and gives an increasing non-negative integral value each time it is used.

I\'m interested to learn w

相关标签:
16条回答
  • 2020-11-29 00:53

    I intend to use __COUNTER__ to give every file in our codebase a unique identifier, so that that unique code can be used in logging ASSERTs in an embedded system.

    This method is much more efficient than using strings to store filenames (using __FILE__), especially on an embedded system with tiny ROM. I thought about the idea whilst I was reading this article - Assert Yourself on Embedded.com. It's a shame that it only works with GCC-based compilers though.

    0 讨论(0)
  • 2020-11-29 00:56

    It is used by Boost.Asio to implement stackless coroutines.

    See this header file and examples.

    Resulting coroutines look like this:

    struct task : coroutine
    {
      ...
      void operator()()
      {
        reenter (this)
        {
          while (... not finished ...)
          {
             ... do something ...
             yield;
             ... do some more ...
             yield;
           }
         }
       }
       ...
    };
    
    0 讨论(0)
  • 2020-11-29 00:56

    In this blog post it is used for simulating the defer statement of golang in C++11.

    template <typename F>
    struct privDefer {
        F f;
        privDefer(F f) : f(f) {}
        ~privDefer() { f(); }
    };
    
    template <typename F>
    privDefer<F> defer_func(F f) {
        return privDefer<F>(f);
    }
    
    #define DEFER_1(x, y) x##y
    #define DEFER_2(x, y) DEFER_1(x, y)
    #define DEFER_3(x)    DEFER_2(x, __COUNTER__)
    #define defer(code)   auto DEFER_3(_defer_) = defer_func([&](){code;})
    

    Then you can do:

    int main()
    {
        FILE* file = open("file.txt");
        defer(fclose(file));
    
        // use the file here
        // ....
    }
    
    0 讨论(0)
  • 2020-11-29 01:01

    I've used it to generate unique types in this article: http://www.codeproject.com/Articles/42021/Sealing-Classes-in-C

    0 讨论(0)
  • 2020-11-29 01:02

    If I'm understanding the functionality correctly, I wished I had that functionality when I was working in Perl, adding an Event Logging function into an existing GUI. I wanted to ensure that the needed hand testing (sigh) gave us complete coverage, so I logged every test point to a file, and logging a __counter__ value made it easy to see what was missing in the coverage. As it was, I hand coded the equivalent.

    0 讨论(0)
  • 2020-11-29 01:03

    A usage is in TensorFlow's REGISTER_KERNEL_BUILDER macro. Each TensorFlow Op could have one or more kernels as its implementations. These kernels are registered with a registrar. The registration of a kernel is done by defining a global variable -- the constructor of the variable can do the registration. Here the authors use __COUNTER__ to give each global variable a unique name.

    #define REGISTER_KERNEL_BUILDER(kernel_builder, ...) \
      REGISTER_KERNEL_BUILDER_UNIQ_HELPER(__COUNTER__, kernel_builder, __VA_ARGS__)
    
    #define REGISTER_KERNEL_BUILDER_UNIQ_HELPER(ctr, kernel_builder, ...) \
      REGISTER_KERNEL_BUILDER_UNIQ(ctr, kernel_builder, __VA_ARGS__)
    
    #define REGISTER_KERNEL_BUILDER_UNIQ(ctr, kernel_builder, ...)          \
      static ::tensorflow::kernel_factory::OpKernelRegistrar                \
      registrar__body__##ctr##__object(                                 \
          SHOULD_REGISTER_OP_KERNEL(#__VA_ARGS__)                       \
          ? ::tensorflow::register_kernel::kernel_builder.Build()   \
          : nullptr,                                                \
          #__VA_ARGS__, [](::tensorflow::OpKernelConstruction* context) \
                -> ::tensorflow::OpKernel* {                \
                  return new __VA_ARGS__(context);          \
                });
    
    0 讨论(0)
提交回复
热议问题