【问题标题】:Determine the expansion of a C macro确定 C 宏的扩展
【发布时间】:2018-07-03 16:44:46
【问题描述】:

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

测试.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 有多大,所以我可以用另一种语言(python 通过 ctypes)制作一个结构,并知道我需要多少空间。我知道对于结构,我可以使用 pahole,但希望只使用 gcc 和更一般的情况(比如不在结构中的全局数组)。

【问题讨论】:

  • 我已将问题阅读了两遍。无法理解您在问什么。
  • 不是(1+10)最终值吗?你想要什么输出?
  • 类似printf("'%s" %d\n", #CCC, CCC);的东西可以上报宏名和扩展吗?
  • 宏处理是一个孤注一掷的交易。
  • 代码可以使用 _Static_assert() 在编译时测试该值,以达到更高级别的合规性目标 _Static_assert(CCC &gt; 0 &amp;&amp; CCC &lt; 20, "CCC out of expected range");

标签: c gcc c-preprocessor preprocessor-directive


【解决方案1】:

预处理器永远不会创建

#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)。

【讨论】:

    【解决方案2】:
    #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));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      • 2010-11-02
      相关资源
      最近更新 更多