The*_*ect 10 c gcc include c-preprocessor
我遵循我编译的代码 gcc
#include<stdio.h>
#include<stdbool.h>
#define true 9
int main() {
printf("TRUE = %d\n",true);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到错误
test.c:3:0: warning: "true" redefined [enabled by default]
In file included from test.c:2:0:
/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdbool.h:34:0: note: this is the location of the previous definition
Run Code Online (Sandbox Code Playgroud)
但是当我改变代码时
#include<stdio.h>
#define true 9
#include<stdbool.h>
int main() {
printf("TRUE = %d\n",true);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
TRUE = 1
Run Code Online (Sandbox Code Playgroud)
题:
我在第一种情况下理解错误的原因但在第二种情况下,当我true在我之前定义时#include<stdbool.h>,为什么允许重新定义true?
更新:
这是stdbool.h.
前几行是
#ifndef _STDBOOL_H
#define _STDBOOL_H
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
Run Code Online (Sandbox Code Playgroud)
这与余浩的回答完全不同.
在文件中stdbool.h,代码可能如下所示:
#ifdef true
#undef true
#define true 1
#endif
Run Code Online (Sandbox Code Playgroud)
在以前定义宏时,您应该这样做.另一个类似的技巧是这样的:
#ifndef MAGIC
#define MAGIC 42
#endif
Run Code Online (Sandbox Code Playgroud)
编辑
除了'#warning'生成的警告之外,所有警告都会在GCC处理系统标头时被抑制.系统标题中定义的宏在任何扩展的位置都不受几个警告的影响.
这很容易通过研究stdbool.h来认识到#ifdef ... #endif围绕定义没有"保护" true.
此外,gcc确实只是为了解决系统头文件中的问题而提出的警告*1.
使用gcc的选项-isystem使第一个示例表现得像第二个.
声明操作系统和运行时库接口的头文件通常不能严格符合C语言编写.因此,GCC会在系统头文件中给出代码特殊处理.GCC处理系统标题时,除"#warning"(参见"诊断")生成的警告之外的所有警告都将被禁止.系统标题中定义的宏在任何扩展的位置都不受几个警告的影响.当我们发现警告由于系统头中定义的宏中的代码而产生大量误报时,会临时授予此免疫权.
[...]
-isystem命令行选项将其参数添加到目录列表以搜索标头,就像-I一样.在该目录中找到的任何标头都将被视为系统标头.
*1:系统标题是<>括号中包含的标题.