Has anyone ever had a use for the __COUNTER__ pre-processor macro?
我有兴趣了解是否有人使用过它,它是否值得标准化?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | struct TLock { void Lock(); void Unlock(); } g_Lock1, g_Lock2; struct TLockUse { TLockUse( TLock &lock ):m_Lock(lock){ m_Lock.Lock(); } ~TLockUse(){ m_Lock.Unlock(); } TLock &m_Lock; }; void DoSomething() { TLockUse lock_use1( g_Lock1 ); TLockUse lock_use2( g_Lock2 ); // ... } |
号
命名锁使用的名称会变得单调乏味,如果它们不是全部声明在块的顶部,甚至可能成为错误的来源。你怎么知道你是在
1 2 3 4 5 6 7 8 9 10 | #define CONCAT_IMPL( x, y ) x##y #define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y ) #define USE_LOCK( lock ) TLockUse MACRO_CONCAT( LockUse, __COUNTER__ )( lock ) void DoSomething2() { USE_LOCK( g_Lock1 ); USE_LOCK( g_Lock2 ); // ... } |
但是不要因为我调用了对象锁这个事实而挂掉——任何需要在匹配的对中被调用的函数都符合这个模式。在给定的块中,您甚至可能在同一个"锁"上有多个用途。
我在编译时断言宏中使用它来让宏为一个将是唯一的typedef创建一个名称。见
- 在C中构建时断言表达式的方法
如果你想要血淋淋的细节。
除了调试宏,我从来没有用过它。说起来很方便
1 2 3 | #define WAYPOINT \ do { if(dbg) printf("At marker: %d ", __COUNTER__); } while(0); |
它在Xcover代码覆盖率库中使用,用于标记执行通过的行,以查找未覆盖的行。
I'm interested to learn whether anyone's ever used it,
号
是的,但是从本问答中的许多例子中可以看出,标准化的
只有在计数每次必须增加一个的情况下,或者它必须在多个
and whether it's something that would be worth standardising?
号
与
一个定义规则的违反是很难捕捉的,并且可能造成错误和安全风险。
即使您从未发布使用
如果我正确理解了这些功能,我希望在Perl中工作时拥有这些功能,在现有的GUI中添加一个事件日志记录函数。我想确保所需的手工测试(SIGH)给我们提供了完整的覆盖范围,所以我将每个测试点都记录到一个文件中,并记录一个
它被boost.asio用来实现无堆栈协程。
请参阅此头文件和示例。
结果协程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | struct task : coroutine { ... void operator()() { reenter (this) { while (... not finished ...) { ... do something ... yield; ... do some more ... yield; } } } ... }; |
。
我在本文中使用它来生成独特的类型:http://www.codeproject.com/articles/42021/sealing-classes-in-c
在我们的代码中,我们忘记了为一些产品添加测试用例。我现在实现了一些宏,这样我们就可以在编译时断言我们为每个要添加或删除的产品都有测试用例。
它在Clickhouse的度量系统中使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | namespace CurrentMetrics { #define M(NAME) extern const Metric NAME = __COUNTER__; APPLY_FOR_METRICS(M) #undef M constexpr Metric END = __COUNTER__; std::atomic<Value> values[END] {}; /// Global variable, initialized by zeros. const char * getDescription(Metric event) { static const char * descriptions[] = { #define M(NAME) #NAME, APPLY_FOR_METRICS(M) #undef M }; return descriptions[event]; } Metric end() { return END; } } |
。
TensorFlow的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #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); \ }); |
与
我打算使用
这个方法比使用字符串来存储文件名(使用