【问题标题】:#define and #include order in CC中的#define和#include顺序
【发布时间】:2013-09-28 06:54:49
【问题描述】:

我使用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

问题:

我理解第一种情况下出错的原因,但在第二种情况下,当我在#include&lt;stdbool.h&gt; 之前定义true 时,为什么允许重新定义true

更新:

这里是stdbool.h

前几行是

#ifndef _STDBOOL_H
#define _STDBOOL_H

#ifndef __cplusplus

#define bool    _Bool
#define true    1
#define false   0

这和于浩的answer完全不同。

【问题讨论】:

  • 我希望你没有认真考虑定义真实
  • @Bathsheba 我认为 OP 正在做一个测试,所以他需要一个不同于 1 的值来查看哪个宏在工作。

标签: c gcc include c-preprocessor


【解决方案1】:

在文件stdbool.h中,代码可能如下所示:

#ifdef true
#undef true
#define true 1
#endif

如果之前定义了宏,您也应该这样做。另一个类似的技巧是这样的:

#ifndef MAGIC
#define MAGIC 42
#endif

编辑

原来这是gcc's feature,详情请参阅@alk's answer

在 GCC 处理系统标头时,所有警告(由“#warning”生成的警告除外)都会被抑制。系统标头中定义的宏在展开时不会受到一些警告的影响。

【讨论】:

  • 嗯,它必须是#ifdef,然后是#undef,因为在第二个示例中,打印的是来自stdbool.h 的值而不是手册#define
  • "... 代码可能看起来像 ...":但事实并非如此。请参阅我对这个问题的回答。
【解决方案2】:

嗯,你的警告已经说明了:

test.c:3:0: warning: "true" redefined [enabled by default]

GCC 允许您重新定义值,除非您明确告诉它不要这样做。您可以为此使用 -Werror。

【讨论】:

    【解决方案3】:

    虽然Yu Hao 给出了possible answer 的问题,但这里的情况确实有所不同。

    这可以很容易地通过查看stdbool.h 来证明true 的定义周围没有#ifdef ... #endif“守卫”。

    此外,gcc 确实简单地隐藏了应针对系统标头中的问题给出的警告*1

    使用 gcc 的选项 -isystem 使第一个示例的行为类似于第二个。

    From the gcc manual:

    声明操作系统和运行时库接口的头文件通常不能用严格符合的 C 语言编写。因此,GCC 对系统头文件中的代码进行特殊处理。在 GCC 处理系统标头时,除由“#warning”(请参阅​​诊断)生成的警告之外的所有警告都将被抑制。系统标头中定义的宏在扩展时不受一些警告的影响。当我们发现由于系统头文件中定义的宏中的代码而导致警告产生大量误报时,这种豁免权是临时授予的。

    [...]

    -isystem 命令行选项将其参数添加到目录列表中以搜索标题,就像 -I 一样。在该目录中找到的任何标头都将被视为系统标头。


    *1:系统标头是包含在&lt;&gt; 括号中的标头。

    【讨论】:

    • -isystem 似乎没有在gcc 中为我生成警告,但+1 这是一个更好的解释。
    • @ShafikYaghmour:对不起,我把它弄混了。请查看我更正后的答案。
    • @alk 由于“GCC 对在系统头文件中找到的代码进行特殊处理”而导致警告没有错误?
    • @TheKojuEffect:是的。但请注意,这种“特殊处理”不是指的是错误,而只是指警告。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 2014-01-26
    • 2013-08-04
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 2011-03-31
    • 2013-03-06
    相关资源
    最近更新 更多