c 语言里面 #if 不可以这样用吗?

2022-10-22 15:34:32 +08:00
 amiwrong123
typedef enum {
    log_level_error = 0,
    log_level_warning = 1,
    log_level_info = 2,
    log_level_dbg = 3,
    log_level_all = 4,
} my_log_level;

#define SMALL 1
#define LARGE 4

static const int current_log_level = log_level_info;

int main()
{
#if (current_log_level > SMALL)
    int b;
#endif

#if (current_log_level > log_level_error)
    int b;
#endif
    b = 2;

    return 0;
}

可能我这个问题有点蠢,但为啥我上面的程序会编译报错呢,两种形式都没有把int b;给编译到,对于#if的用法有点不太明白了。

1800 次点击
所在节点    C
13 条回复
westoy
2022-10-22 15:36:18 +08:00
这不是运行时的 if , 这是宏里的 if 啊, 编译前会替换掉的, 拿来处理变量当然会有问题了
overloadtanxxx2
2022-10-22 15:37:02 +08:00
#if 是预编译
预编译 比 编译早呀。
赋值是编译期间的操作。预编译的时候还没赋值
overloadtanxxx2
2022-10-22 15:38:16 +08:00
你试试 改成 > -1 ,看看 int b 能不能编译到。估计就能编译到了
amiwrong123
2022-10-22 15:41:13 +08:00
@westoy #1
@overloadtanxxx2 #3
谢谢,我大概理解了,所以我这个程序正确的写法应该是把:
static const int current_log_level = log_level_info;
替换成
#define current_log_level 2

最好也把 枚举定义也替换成宏:
typedef enum {
log_level_error = 0,
log_level_warning = 1,
log_level_info = 2,
log_level_dbg = 3,
log_level_all = 4,
} my_log_level;
替换为
#define log_level_error 0
#define log_level_warning 1
#define log_level_info 2
#define log_level_dbg 3
#define log_level_all 4

应该是这样做吧
overloadtanxxx2
2022-10-22 15:49:27 +08:00
@amiwrong123 感觉没什么毛病。肯定可以达到 定义不同等级打印不同等级日志的效果
overloadtanxxx2
2022-10-22 16:00:17 +08:00
程序符号表有一个变量 current_log_level 。在程序跑之前。根据不同编译器,值不一样。一般是 0 。预编译运行时,这个值不符合条件
amiwrong123
2022-10-22 16:02:28 +08:00
@overloadtanxxx2 #6
ok ,理解你的意思,总之,在#if 里面,不可以依赖这种全局变量的值,就算能依靠也是不可靠的
ligiggy
2022-10-22 16:19:15 +08:00
推荐看一本书,《程序员的自我修养—链接、装载与库》。
jimmy980352
2022-10-22 16:30:34 +08:00
可能编译器认为会出现变量 b 不被定义的情况,试试#if....#elif...#else...#endif 的每个区间都定义 b
amiwrong123
2022-10-22 16:35:23 +08:00
@jimmy980352 #9
嗯,你意思我理解了。留出一个#else...来保证编译到 int b;

不过我的目的是:用 打印日志等级 来控制一些打印。

正常来说,我那个程序会写成:
#if (current_log_level > log_level_error)
printf("error log\n");
#endif

但是我又发现这么写 好像不能起到控制编译的作用,实际效果是:我那么写 是永远不会被编译到。
iamzuoxinyu
2022-10-22 16:52:31 +08:00
@amiwrong123 为什么不干脆
#if LOG_WARN
// print sth
#endif

#if LOG_ERROR
// print err
#endif

这样,编译时直接 gcc -DLOG_WARN -DLOG_ERROR 想怎么指定怎么指定……
iamzuoxinyu
2022-10-22 16:54:09 +08:00
#ifdef 更好。
lance6716
2022-10-22 22:10:17 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/888951

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX