关于-Wundef选项未对#ifdef中的未定义符号LINUX触发告警的原因及解决方法咨询
解答:
-Wundef为何不对#ifdef LINUX告警,以及如何让它触发告警 先看你的代码示例:
// program.cpp #include <iostream> int main() { #ifdef LINUX std::cout << "Linux\n"; #elif MAC std::cout << "Mac\n"; #elif WINDOWS std::cout << "Windows\n"; #elif BSD std::cout << "BSD\n"; #else std::cout << "Something else\n"; #endif return 0; }
当用clang++ -Wundef -DBSD -o program program.cpp或者g++ -Wundef -DBSD -o program program.cpp编译时,确实会得到针对MAC和WINDOWS的告警:
program.cpp:6:7: warning: 'MAC' is not defined, evaluates to 0 [-Wundef] #elif MAC ^ program.cpp:8:7: warning: 'WINDOWS' is not defined, evaluates to 0 [-Wundef] #elif WINDOWS ^ 2 warnings generated.
根据GCC手册对-Wundef的定义:
-Wundef Warn if an undefined identifier is evaluated in an "#if" directive. Such identifiers are replaced with zero.
你的猜测完全正确——LINUX用#ifdef包裹,所以不会触发-Wundef告警。原因在于:
#ifdef/#ifndef只是做"标识符是否被定义"的检查,不会去计算标识符的具体值,自然不会触发"未定义标识符被求值"的告警;- 而
#elif MAC本质上等价于#elif defined(MAC) && MAC,这里的第二个部分会去计算MAC的值——如果MAC没定义,会被替换成0,这就正好命中了-Wundef的触发条件。
如何让未定义的LINUX触发告警?
你需要修改代码中的条件判断结构,把#ifdef LINUX改成需要求值的形式,比如直接用#if LINUX,或者更明确的#if defined(LINUX) && LINUX。修改后的代码如下:
// 修改后的核心条件判断 #if LINUX std::cout << "Linux\n"; #elif MAC std::cout << "Mac\n"; #elif WINDOWS std::cout << "Windows\n"; #elif BSD std::cout << "BSD\n"; #else std::cout << "Something else\n"; #endif
这样当LINUX未定义时,编译器在处理#if LINUX时会把未定义的LINUX替换成0,进而触发-Wundef的告警。
需要注意的是:目前GCC和Clang没有单独的编译选项能让-Wundef监控#ifdef/#ifndef里的未定义标识符,因为这类指令不涉及求值操作,不在-Wundef的设计范围内,只能通过调整代码结构来实现你的需求。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

