是否有办法通过检查编译对象或在.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)
这要求我仍然知道AAA
和BBB
是什么。
编译:
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和更一般的情况(例如,不在结构中的全局数组)来做到这一点。
答案 0 :(得分:2)
预处理器永远不会创建
#define CCC (1+10)
CCC
的扩展始终为(AAA+BBB)
;只是重新扫描了宏扩展的结果以扩展更多宏,此时AAA
和BBB
分别变成了1
和10
。
也许更清楚的例子是
#define AAA 1
#define CCC AAA
#define AAA "hello"
size_t x = sizeof CCC;
此代码将扩展为"hello"
,而不是1
。 CCC
的值始终为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));
}