如何使用gcc捕获未定义的预处理器宏?

时间:2016-09-05 17:31:06

标签: c debugging macros c-preprocessor

我一直在处理一段代码中有一个被忽视的derp:

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

#define MAX_N_LENGTH 

/*function prototypes*/

int main(){
...
}

删除上下文应该很容易找到:#define MAX_N_LENGTH应该已阅读#define MAX_N_LENGTH 9。我不知道那个尾随常数在哪里。

由于该宏仅以char buf[ MAX_N_LENGTH + 1]的形式在一个地方使用,因此跟踪和调试程序非常困难。

有没有办法使用gcc编译器来捕获像这样的错误?

4 个答案:

答案 0 :(得分:3)

您可以使用char buf[1 + MAX_N_LENGTH],因为char buf[1 +]不应使用错误消息error: expected expression before ']' token进行编译:

http://ideone.com/5m2LYw

答案 1 :(得分:2)

你所拥有的不是一个未定义的宏。这是一个空的宏。定义的空宏是完全合法的,因为你可以测试它们的定义。

它们在实现头文件中使用了很多,尽管所有这些空宏都将在实现命名空间中,这意味着它们将包含两个下划线或下划线后跟一个大写字母。

你可以做的是测试你是否有一个不在实现命名空间中的空宏,你可以用:

cpp -dM YOUR_FILE.c |
     cut -d\  -f2- | grep '^[a-zA-Z0-9_]* $' |grep -v -e __ -e ^_[A-Z]

对于您的示例,它应该只输出MAX_N_LENGTH

答案 2 :(得分:1)

一般意义上不可能捕获此错误,因为它不是错误。有很多情况需要这种行为,因此编译器不能将其视为错误或警告。

如果您可以将错误跟踪到某一行,则使用gcc的-E命令行参数将导致它输出预处理器的结果。在这种情况下,您的字符行将转为char buf[+1],这是合法的C代码,但可能引起您的注意,因为您希望它是char buf[9+1]-E会导致gcc打印这些结果,因此您实际上会在gcc的输出中看到char buf[+1]

这样的问题是为什么C ++不鼓励以这种方式使用定义宏(当然,C ++有比C更多的选择,这使得更容易阻止它们)

答案 3 :(得分:1)

您可以使用预处理器捕获宏为0或未定义值的时间:

#define VAR

#if VAR+0 == 0
#error "VAR is either 0 or defined without a value."
#endif