确定C宏的扩展

时间:2018-07-03 16:44:46

标签: c gcc c-preprocessor preprocessor-directive

是否有办法通过检查编译对象或在.c或.h文件上运行某种形式的gcc -E来确定扩展的C宏的“最终值”?

test.h

#define AAA 1
#define BBB 10
#define CCC (AAA+BBB)

test.c

#include <stdio.h>
#include "test.h"

int main(){
   printf("%d\n", CCC);
   return 0;
}

因此有某种方法可以获取扩展值:

#define CCC 11

#define CCC (1+10)

如果使用编译

gcc -dM -E test.c | grep CCC 

gcc -dD -E test.c | grep CCC

输出

#define CCC (AAA+BBB)

这要求我仍然知道AAABBB是什么。

编译:

gcc -E test.c

给予(跳过样板):

# 4 "test.c"
int main(){
printf("%d\n", (1+10));
return 0;
}   

虽然扩展了CCC,但现在我丢失了映射回CCC的映射。

编辑: 尚不清楚,我想以某种方式确定CCC是什么(11或1 + 10(如gcc -E示例所示,它仅插入(1 + 10)而不是11)),最好不更改代码本身。Printf在MRE中使用是一个坏主意,我实际上想到的是这样的代码:

struct my_struct {
    int my_array[CCC]
    ... other stuff ...
}

问题是my_array有多大,所以我可以用另一种语言(通过ctypes通过python)构造一个结构,并知道我需要多少空间。我知道我可以使用pahole的结构,但希望仅使用gcc和更一般的情况(例如,不在结构中的全局数组)来做到这一点。

2 个答案:

答案 0 :(得分:2)

预处理器永远不会创建

#define CCC (1+10)

CCC的扩展始终为(AAA+BBB);只是重新扫描了宏扩展的结果以扩展更多宏,此时AAABBB分别变成了110

也许更清楚的例子是

#define AAA 1
#define CCC AAA
#define AAA "hello"

size_t x = sizeof CCC;

此代码将扩展为"hello",而不是1CCC的值始终为AAA;只是在处理size_t x = sizeof CCC;时,AAA本身就会变成"hello"

此示例还演示了可以重新定义宏的原因,因此甚至可能没有一个单独的答案“ CCC的值是什么?”。

这就是为什么没有简单的编译器调用或切换的原因;您想要的东西根本不存在。

也就是说,如果您可以使用自定义代码,则只需运行例如

#define AAA 1
#define BBB 10
#define CCC (AAA+BBB)
CCC

通过gcc -P -E,结果将仅为(1+10)

答案 1 :(得分:1)

#include <stdio.h>

#define AAA 1
#define BBB 2
#define CCC (AAA+BBB)

#define STRINGIFY(x) #x
#define PASTE(x) STRINGIFY(x)


int main(void)
{
  printf("CCC = '%s'\n", PASTE(CCC));
}

打印

CCC = '(1+10)'

打印相同内容的替代版本:

#include <stdio.h>

#define AAA 1
#define BBB 2
#define CCC (AAA+BBB)

#define STRINGIFY(x) #x
#define INTERMEDIATE(x) #x " = '" STRINGIFY(x) "'"

int main(void)
{
  printf("%s\n", INTERMEDIATE(CCC));
}