author: hjjdebug
date: 2025年 03月 06日 星期四 14:48:58 CST
description: 在编译阶段查看宏定义的值
文章目录
1. 前言
在C代码中看到了如下代码
#ifdef __GNUC__
#define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
#else
#define AV_GCC_VERSION_AT_LEAST(x,y) 0
#endif
#if AV_GCC_VERSION_AT_LEAST(2,6)
....
#else
....
#endif
那么,我就有点迷糊了, 那这个 GNUC 到底定义了没有呢? 如果定义了,又是多少呢?
2. 查看宏定义的处理手段
想搞清楚这个问题是有好几种手段的.
2.1 第一种: 用printf 来打印.
在main() 函数中开始的地方添加
printf(“GNUC is %d\n”, GNUC);
这里我们假定__GNUC__ 是整形值.
然后执行编译出的代码.
缺点: 还得编译通过程序,还得执行代码.
2.2 第二种: 用预处理命令.
gcc -c -E -dD -o main.dD main.c
然后可查看所有的宏定义
缺点: 杀鸡用牛刀了,不是太直接,虽然它能很好的解决问题.
不过这确实是一种推荐的方法, 第一种方法也不错.
2.3 第三种: 在编译期就让程序直接打印出宏的值.
我们知道,#warning 预处理指令是可以打印字符串的,但我试了半天不能打印宏的值
#pragma message() 预处理指令也可以输出字符串,用它可以打印出宏的值.
#define SIZE 100
#pragma message("SIZE = " VAL(SIZE))
关键是对SIZE 的引用应该怎样写? c 代码printf中SIZE 本身就是引用,bash中对变量加上$为引用
在预处理中又怎样引用值呢?
在宏展开中, 宏参数会被替换为值
所以要把VAL(x) 写成两个宏
#define VAL(x) VAL_1(x) #这样VAL(SIZE) 被展开为VAL_1(100)
#define VAL_1(x) #x #VAL_1(100) 被字符串化为"100"
3. 编译器打印宏定义的值举例:
$ cat main.c
#include <stdio.h>
// 第一层宏:把宏参数x展开,传递给宏VAL_1
#define VAL(x) VAL_1(x)
// 第二层宏:把宏参数字符串化
#define VAL_1(x) #x
#define SIZE 100
#define VERSION "6.2.100"
// 编译时输出
//warning 中不支持宏展开操作,所以打印不出宏的值
//#warning VAL(SIZE)
//#pragama message 中支持宏展开操作, 可以打印宏的值
#pragma message("SIZE = " VAL(SIZE))
#pragma message("VERSION = " VAL(VERSION))
#pragma message("HAHA = " VAL(HAHA))
int main(void)
{
return 0;
}
hjj@hjj-7090:~/test/macro2$ cat Makefile
all: main
main:main.c
gcc -o main main.c
clean:
rm *.o main
查看结果
hjj@hjj-7090:~/test/macro2$ make
gcc -o main main.c
main.c:14:9: note: #pragma message: SIZE = 100
14 | #pragma message("SIZE = " VAL(SIZE))
| ^~~~~~~
main.c:15:9: note: #pragma message: VERSION = "6.2.100"
15 | #pragma message("VERSION = " VAL(VERSION))
| ^~~~~~~
main.c:16:9: note: #pragma message: HAHA = HAHA
16 | #pragma message("HAHA = " VAL(HAHA))
| ^~~~~~~
4. 小结:
#warning 中不支持宏展开操作,它直接把后面当字符串了,所以打印不出宏的值
#pragama message() 中支持宏展开操作, 可以打印宏的值,但需要定义2个宏