C 预处理器魔法

标签 c visual-studio c-preprocessor

我正在尝试使用预处理器技巧来声明一个魔法变量。像这样:

DECLARE(x)

应该扩展到

int _DECLARED_VARIABLE_x_LINE_12

如果声明位于输入源的第 12 行。我试图使用 ## 标记粘贴命令和 __LINE__ 宏,但我要么在那里得到一个未解释的“__LINE__”,要么预处理器似乎完全忽略了我的线。我目前的猜测是:

 #define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__

最佳答案

在这种情况下,通常的技巧是使用第二个宏。然而,这似乎不适用于 GCC(MacOS X 10.6.4 上的 4.5.1),并且需要第三级宏:

#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__

#define DECLARE42(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE41(x, line) DECLARE42(x, line)
#define DECLARE40(x) DECLARE41(x, __LINE__)

int DECLARE(y);
int DECLARE40(c) = 129;

“gcc -E”的输出:

# 1 "magicvars.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "magicvars.c"






int _DECLARED_VARIABLE_y_LINE___LINE__;
int _DECLARED_VARIABLE_c_LINE_8 = 129;

我不确定我是否能很好地解释为什么需要第三级宏。

我也很想知道您在创建这些变量后将如何引用它们。


在设法找到有效的变体之前,我经历了许多变体:

#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__

#define DECLARE11(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE10(x) DECLARE11(x, __LINE__)

#define DECLARE23(line) _LINE_ ## line
#define DECLARE22(x) _DECLARED_VARIABLE_ ## x
#define DECLARE21(x, line) DECLARE22(x) ## DECLARE23(line)
#define DECLARE20(x) DECLARE21(x, __LINE__)

#define DECLARE32(line) _LINE_ ## line
#define DECLARE31(x, line) _DECLARED_VARIABLE_ ## x ## DECLARE32(line)
#define DECLARE30(x) DECLARE31(x, __LINE__)

#define DECLARE42(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE41(x, line) DECLARE42(x, line)
#define DECLARE40(x) DECLARE41(x, __LINE__)


int DECLARE(y);
int DECLARE10(z) = 12;
int DECLARE20(a) = 37;
int DECLARE30(b) = 91;
int DECLARE40(c) = 129;

享受解决为什么不工作的人不工作的乐趣。但是,他们确实将我指向了工作答案。 (我注意到 Sun C 编译器在相同的输入上产生与 GCC 基本相同的结果。)

关于C 预处理器魔法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3580533/

相关文章:

c++ - 将右值引用分配给成员变量

c++ - 如何在正则表达式中表示 C++ 函数名?

c++ - Variadac 宏将宏应用于所有参数

.net - MSBuild 项目引用 :private ("Copy Local") - what are the allowed values and behaviour?

c++ - 使用宏计算源文件行数?

c++ - 为什么宏扩展遵循模板扩展?

c++ - 动态字符串数组 - C

c - 在 C 编程中存储日志/错误消息

c - 如何将此代码更改为递归函数?

c++ - 使用函数指针将 C 转换为 CPP