【问题标题】:Expand __COUNTER__ macro once per source file每个源文件展开一次 __COUNTER__ 宏
【发布时间】:2013-07-25 12:11:19
【问题描述】:

我正在尝试编写一个宏,它将每个源文件仅扩展一次 __COUNTER__ 宏。我完全理解宏如何与它们的扩展一起工作,但我在这个方面遇到了困难。我想在文件顶部展开一次 __COUNTER__ 宏,然后对该定义的每个引用都不会将 __COUNTER__ 展开到下一个数字。

所以我想将__COUNTER__ 完全扩展为一个值,然后在当前工作源文件中始终使用该值。

我只能使用 C 可用的功能。

【问题讨论】:

  • 模板元编程,您可以在...编译时“生成”运行代码的 ID。
  • 我仅限于使用 C,所以这个解决方案必须在预处理器上
  • 该值是否需要在编译时可用?还是可以等到运行时?
  • 必须是编译时间。

标签: c xcode4 llvm c-preprocessor


【解决方案1】:

__COUNTER__ 扩展名(我想您使用的是 gcc 系列的编译器)对于这种用途来说太受限制了。困难在于,如果你把它放到另一个宏中,比如TOTO,它不会在定义时扩展,而只是在使用时扩展。所以每次调用TOTO 都会产生一个新的计数器值。

P99 我有一个便携式替代品,它通过一些#includehackery 实现了这个目标。 P99_FILEID 是每个文件的标识符,P99_LINEID 是编译单元中所有行的唯一 ID(但要小心使用)。

如果您只需要一个编译时间常数并且预处理器本身没有任何内容,那么另一种选择是在枚举常数中使用计数器。

enum { toto_id = __COUNT__, }; 

【讨论】:

  • 这看起来很像我需要的,我可以在哪里下载你的 P99,我在哪里可以看到它的许可证?
  • @FelixJones,您可以通过主页 p99.gforge.inria.fr 找到所有内容。许可证是 QPL,但希望很快会更改为 GPL。
  • 似乎不起作用,每个文件都有编号 1111。我猜这是因为宏没有保留在源输入之间,我将不得不看看我是否可以将其设置为全局为我的编译器定义
  • 文档说“一个标识包含文件“p99_id.h”的不同时间的 id,因此您必须将该文件包含在每个标头和 .c 文件中以更新计数器。
  • 啊,恐怕不会发生。我只需要处理我的软件中容易出错的部分
猜你喜欢
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
相关资源
最近更新 更多