条件 C 预处理器指令

标签 c macros c-preprocessor

在我的代码中我有一个宏:

#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/

相关文章:

C 的汇编覆盖率

vim - 是否可以使用 Vim 的普通命令来记录和运行递归宏?

检查宏参数是否为文字

c - 如何在循环中实例化新的结构实例

Objective-C 与 C 速度

c - 我必须创建这个学生数据程序。有这个警告我只是无法弄清楚

c - 为什么将这些宏函数转换为函数不能正常工作?

C 预处理器变量连接 "."

objective-c - 访问预处理器宏定义的值

c++ - 是否可以让 gnu cpp 保留包含宏?