怎么把counter放到前面c语言,有人曾经使用过__COUNTER__预处理器宏吗?

有人曾经使用过__COUNTER__预处理器宏吗?

__COUNTER__符号由VC ++和GCC提供,并在每次使用时给出递增的非负整数值。

我有兴趣了解是否有人使用过它,并且它是否值得标准化?

dcw asked 2020-06-23T14:37:19Z

13个解决方案

45 votes

lock_use4在您需要唯一名称的任何地方都非常有用。 我已经将它广泛用于RAII样式的锁和堆栈。 考虑:

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 );

// ...

}

命名锁的使用很麻烦,而且如果未在块的顶部全部声明它们,甚至可能成为错误的来源。 您怎么知道您使用的是lock_use4还是lock_use11? 这也不必要地污染了命名空间-我永远不需要按名称引用锁使用对象。 所以我用__COUNTER__:

#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 );

// ...

}

但是请不要挂断我所谓的对象锁的事实-需要在匹配对中调用的任何函数都适合这种模式。 您甚至可能在给定块中的同一“锁”上有多种用途。

answered 2020-06-23T14:38:01Z

13 votes

我在编译时断言宏中使用了该宏,以使该宏为唯一的typedef创建名称。 看到

在C语言中构建时ASSERT表达式的方法

如果您需要血腥细节。

Michael Burr answered 2020-06-23T14:38:29Z

12 votes

除了DEBUG宏外,我从未将其用于任何其他用途。 说起来很方便

#define WAYPOINT \

do { if(dbg) printf("At marker: %d\n", __COUNTER__); } while(0);

Charlie Martin answered 2020-06-23T14:38:49Z

11 votes

xCover代码覆盖库中使用了它,以标记执行通过的行,以查找未覆盖的行。

JamieH answered 2020-06-23T14:37:31Z

7 votes

我很想知道是否有人使用过它,

是的,但是您可以从本问答中的许多示例中看到,标准化的__COUNTER__在大多数情况下也足够了。

__COUNTER__仅在计数每次必须增加一,或者必须具有多个__LINE__文件的连续性的情况下才真正必要。

以及是否值得标准化?

与__LINE__不同,__COUNTER__非常危险,因为它取决于所包含的头文件和顺序。 如果两个.cpp文件(转换单元)包含使用__COUNTER__的头文件,但该头文件在不同实例中获得不同的计数序列,则它们可能使用同一事物的不同定义,并且违反了一个定义规则。

一键违反规则非常难以发现,并可能产生错误和安全风险。 __COUNTER__的几个用例并没有真正弥补不足和缺乏可伸缩性。

即使您从未发布过使用__COUNTER__的代码,在对枚举序列进行原型制作时也很有用,从而避免了在具体确定成员资格之前分配名称的麻烦。

Potatoswatter answered 2020-06-23T14:39:37Z

3 votes

如果我正确理解该功能,则希望在Perl中工作时可以使用该功能,并在现有GUI中添加一个事件记录功能。 我想确保所需的手动测试(叹气)能够为我们提供完整的覆盖范围,因此我将每个测试点记录到了一个文件中,并记录了__counter__的值可以轻松查看覆盖范围中缺少的内容。 照原样,我手动编码了等效代码。

Leonard answered 2020-06-23T14:39:58Z

2 votes

Boost.Asio使用它来实现无堆栈协程。

请参阅此头文件和示例。

生成的协程看起来像这样:

struct task : coroutine

{

...

void operator()()

{

reenter (this)

{

while (... not finished ...)

{

... do something ...

yield;

... do some more ...

yield;

}

}

}

...

};

StaceyGirl answered 2020-06-23T14:40:26Z

1 votes

我在本文中使用它来生成唯一类型:[http://www.codeproject.com/Articles/42021/Sealing-Classes-in-C]

Francis Xavier answered 2020-06-23T14:40:46Z

0 votes

我打算使用__FILE__为我们代码库中的每个文件赋予唯一的标识符,以便可以将唯一的代码用于记录嵌入式系统中的ASSERT。

与使用字符串存储文件名(使用__FILE__)相比,此方法要高效得多,尤其是在带有微型ROM的嵌入式系统上。 在阅读本文时,我想到了这个主意-在Embedded.com上声明自己。 可惜的是,它只能与基于GCC的编译器一起使用。

thegreendroid answered 2020-06-23T14:41:11Z

0 votes

与__LINE__不同,可以保证__COUNTER__是唯一的。某些编译器允许重置__LINE__。 #include文件也将重置__LINE__。

BSalita answered 2020-06-23T14:41:31Z

0 votes

TensorFlow的__COUNTER__宏中有用法。 每个TensorFlow Op可以有一个或多个内核作为其实现。 这些内核已向注册商注册。 内核的注册是通过定义全局变量完成的-变量的构造函数可以进行注册。 在这里,作者使用__COUNTER__为每个全局变量赋予唯一的名称。

#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); \

});

cxwangyi answered 2020-06-23T14:41:52Z

0 votes

在ClickHouse的指标系统中使用。

namespace CurrentMetrics

{

#define M(NAME) extern const Metric NAME = __COUNTER__;

APPLY_FOR_METRICS(M)

#undef M

constexpr Metric END = __COUNTER__;

std::atomic 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; }

}

Amos answered 2020-06-23T14:42:12Z

0 votes

在我们的代码中,我们忘记为某些产品添加测试用例。 我现在实现了一些宏,因此我们可以在编译时断言对于要添加或删除的每个产品都有测试用例。

Devolus answered 2020-06-23T14:42:32Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值