下面的代码提供了一个警告,用于从指向int的指针进行强制转换
int foo[] = {1,2,3}; #define bar(x) foo[(int)(x) % 3] char *baz = "quux"; bar(baz);
另一方面,以下代码编译时没有任何警告(无论它是否可能导致运行时错误)
#include <ctype.h> // some code char *baz = "quux"; isalpha(baz);
当我打开ctype.h来查看isalpha时,我发现它是一个使用其他几个宏的宏
# define _ISbit(bit) (1 << (bit)) enum { // some identifiers _ISalpha = _ISbit (2),// some identifiers }; extern const unsigned short int **__ctype_b_loc (void) __THROW __attribute__ ((__const__)); # define __isctype(c,type) \ ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type) # define isalpha(c) __isctype((c),_ISalpha)
正如您可能看到的,扩展isalpha宏的结果仍然显式地将指针baz强制转换为int.但是,编译时不会发出任何警告.显然,两段代码执行相同的操作(即将char *转换为int),但是一个给出警告而另一个没有.为什么?
注意:使用具有相同选项的编译命令来编译包含这些代码段的程序.
编译器版本:
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
解决方法
第一个程序没有用gcc 4.7发出警告,但是在版本4.8中发出了警告.
第二个程序不会发出警告,因为宏定义位于系统头中.添加-Wsystem-headers以获取第二个程序的警告.
来自gcc文档(强调我的)
-Wsystem-headers
Print warning messages for constructs found in system header files.
Warnings from system headers are normally suppressed,on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read.