在我的代码中我有一个宏:
#define TPS 1(or 0)
int main()
{
....
if(var)
{
#ifdef TPS
do something
#endif
}
}
但现在,我想将 if(var)
与宏合并,以便实现:
int var=1;
#define TPS (if(var))
int main()
{
int a, b, c;
a=1;b=2;c=3;
#if TPS
printf("a: %d\n", a);
printf("b: %d\n", b);
printf("c: %d\n", c);
#endif
printf("++a: %d\n", ++a);
return 0;
}
即仅当 var=1
时,宏条件内的代码块才应出现
例如,对于 var=1:
int main()
{
int a, b, c;
a=1;b=2;c=3;
printf("a: %d\n", a);
printf("b: %d\n", b);
printf("c: %d\n", c);
printf("++a: %d\n", ++a);
return 0;
}
并且,对于 var=0:
int main()
{
int a, b, c;
a=1;b=2;c=3;
printf("++a: %d\n", ++a);
return 0;
}
如何实现#define TPS
来实现这一目标?
最佳答案
你无法实现你的梦想。
Preprocessing是编译器的最早阶段之一(例如gcc
)。您的 TPS
看起来您希望它的编译行为取决于运行时变量 var
。从概念上讲,编译器首先对源代码进行预处理。您可以使用 gcc -C -E
获取预处理后的文本形式。
在编译时,变量有一个名称,编译器会找到它的位置(但变量在编译期间没有任何值)。在运行时,变量有一个包含值的位置。值在编译时不存在,因此您无法在预处理阶段使用它们。
但是,预处理可以是有条件的,例如
#if WANTPRINT
printf("a: %d\n", a);
#endif
然后您可以将 -DWANTPRINT=1
标志传递(或不传递)给编译器。
你可以编码
int var;
int main() {
int a, b, c;
a=1;b=2;c=3;
if (var) {
printf("a: %d\n", a);
printf("b: %d\n", b);
printf("c: %d\n", c);
};
printf("++a: %d\n", ++a);
return 0;
}
<小时/>
顺便说一句,也许您想在运行时动态加载一些代码?在 Linux 和大多数 Posix 系统上,您可以调用 dlopen(3)和 dlsym 。您甚至可以在某个(临时)文件中生成一些 C 代码, fork 一个进程将其编译为共享对象,然后 dlopen 共享对象,使用 dlsym 获取函数指针> 然后调用它... 另请参阅 this answer .
FWIW,Common Lisp 有一个非常强大的宏系统,能够在运行时“编译”,并在“编译时”进行任意计算。实际上,SBCL运行时可能会生成良好的机器代码......
<小时/>附录
也许您想自定义 GCC 编译器本身的行为。那么你可以考虑使用 MELT (扩展 GCC 的领域特定语言)。但 GCC 尚未启用其预处理的自定义(但主要是其中端,致力于 Gimple 等内部 GCC 表示)
关于条件 C 预处理器指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17964447/