我遵循使用gcc
#include<stdio.h>
#include<stdbool.h>
#define true 9
int main() {
printf("TRUE = %d\n",true);
return 0;
}
我得到错误
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
但是当我改变代码时
#include<stdio.h>
#define true 9
#include<stdbool.h>
int main() {
printf("TRUE = %d\n",true);
return 0;
}
输出:
TRUE = 1
问题:
我理解第一种情况下出错的原因但在第二种情况下,当我在true
之前定义#include<stdbool.h>
时,为什么允许重新定义true
?
更新
这是stdbool.h。
前几行是
#ifndef _STDBOOL_H
#define _STDBOOL_H
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
这与余浩的answer完全不同。
答案 0 :(得分:9)
在文件stdbool.h
中,代码可能如下所示:
#ifdef true
#undef true
#define true 1
#endif
在以前定义宏时,您应该这样做。另一个类似的技巧是这样的:
#ifndef MAGIC
#define MAGIC 42
#endif
修改强>
原来这是gcc's feature,有关详细信息,请参阅@alk's answer。
GCC正在处理系统标题时,将禁止除“#warning”生成的警告以外的所有警告。系统标题中定义的宏在任何扩展的地方都不会受到一些警告的影响。
答案 1 :(得分:7)
尽管Yu Hao给了问题possible answer,但事情确实有所不同。
通过调查stdbool.h
以了解#ifdef ... #endif
的定义周围没有true
“警卫”,可以很容易地证明这一点。
此外,gcc会简单地抑制系统标题 * 1 中的问题。
使用gcc的选项-isystem
使第一个示例的行为与第二个相同。
声明操作系统和运行时库接口的头文件通常不能严格符合C语言编写。因此,GCC会在系统头文件中给出代码特殊处理。 GCC正在处理系统标题时,除了'#warning'(请参阅诊断)生成的警告之外的所有警告都将被禁止。系统标题中定义的宏在任何扩展的地方都不受几个警告的影响。当我们发现警告由于系统头中定义的宏中的代码而产生大量误报时,会临时授予此免疫权。
[...]
-isystem命令行选项将其参数添加到目录列表以搜索标头,就像-I一样。在该目录中找到的任何标头都将被视为系统标头。
* 1:系统标头是<>
括号中包含的标头。
答案 2 :(得分:-1)
嗯,你的警告已经说明了:
test.c:3:0: warning: "true" redefined [enabled by default]
GCC允许您重新定义值,除非您明确告诉它不要。你可以使用-Werror。