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

如何用gcc捕获未定义的预处理器宏?,c,debugging,macros,c-preprocessor,C,Debugging,Macros,C Preprocessor,我一直在编写一段代码,其中有一个被忽略的derp: #include<stdio.h> #include<stdlib.h> #include<limits.h> #define MAX_N_LENGTH /*function prototypes*/ int main(){ ... } #包括 #包括 #包括 #定义最大长度 /*功能原型*/ int main(){ ... } 删除上下文后应该很容易发现:#定义最大长度应该已经阅读了#定义最大长

我一直在编写一段代码,其中有一个被忽略的derp:

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

#define MAX_N_LENGTH 

/*function prototypes*/

int main(){
...
}
#包括
#包括
#包括
#定义最大长度
/*功能原型*/
int main(){
...
}
删除上下文后应该很容易发现:
#定义最大长度
应该已经阅读了
#定义最大长度9
。我不知道尾随常数去了哪里


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


有没有一种方法可以使用gcc编译器捕获像这样的错误?

一般来说,不可能捕获这个错误,因为它不是一个错误。在很多情况下需要这种行为,因此编译器不能将其视为错误或警告

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


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

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

它们在实现头文件中被大量使用,尽管所有这些空宏都将在实现名称空间中,这意味着它们要么包含两个下划线,要么包含一个下划线,后跟一个大写字母

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

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

例如,它应该只输出
MAX\u N\u LENGTH
您可以使用
char-buf[1+MAX\u-N\u LENGTH]
,因为
char-buf[1+]
不应使用错误消息
error:expected expected expression before']'token


当宏为0或定义时没有值时,可以使用预处理器捕捉:

#define VAR

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

请避免在评论中回答问题。
char-buf[MAX\u N\u LENGTH+1]
扩展为
char-buf[+1]
,这是有效的,
gcc
不会对有效代码发出警告。请将问题名称更改为
如何用gcc捕获定义的空预处理器宏?
或其他内容。对于像我这样最终想要在#if指令中查找未定义宏的人,请注意:在gcc中,使用-Wundef(还有)你的意思是
char-buf[MAX\N\u LENGTH+1]
@AlterMann不,
char-buf[+1]
编译,而
char-buf[1+]
不编译。未来的谷歌用户:也看到了;我只能接受一个,但它们都很优秀。