在编译阶段查看宏定义的值


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个宏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值