有人有两次包含stdlib.h的原因吗?

我在这里研究Kilo文本编辑器的代码:

https://github.com/antirez/kilo/blob/master/kilo.c

我注意到包含两次定义的stdlib.h (UPDATE:Comments stdlib.h mine):

 #include  #include  // first time #include  #include  #include  #include  // second time #include  

这只是一个错误吗? 或者有什么东西吗? 我问,因为代码的作者似乎不是犯了很多错误的人。 我不想暗示改变无知。

由于stdlib.h有一个包含守卫,因此将它包含两次是没有意义的。 可能这个错误是由两个文件合并引起的,两个文件都依赖于stdlib.h。

包含标准标题不止一次是没有害处的,尽管这是完全没必要的。

C标准说明如下:

标准标题可以按任何顺序包含在内; 在给定范围内,每个都可以被包含多次,除了包含的效果取决于NDEBUG的定义之外,没有任何效果与仅被包含一次不同。

没有理由两次包含特定的头文件。 如果文件具有适当的包含保护,则第二个包含将不起作用。 如果它没有包含警戒,那么对于typedef的多个定义,您可能会遇到大量错误。

在系统标题的情况下,它们几乎总是包含警卫。 stdlib.h的内容可能如下所示:

 #ifndef _STDLIB_H #define _STDLIB_H 1 ... // type definitions, #defines, declarations, etc. ... #endif /* stdlib.h */ 

第一次包含stdlib.h时, #ifndef将计算为true,定义_STDLIB_H ,并将剩余的内容插入到正在编译的文件中。 第二次包含stdlib.h时, #ifndef将评估为false,因为定义了_STDLIB_H ,并且不再插入#ifndef#endif之间的文件内容。

大多数UNIX / Linux系统都是这样做的。 相比之下,Microsoft以正确管理其特定于操作系统的包含文件而闻名。 如果你按错误的顺序包含它们,你最终会遇到很多错误。

它可以产生影响的唯一情况是,其中一个包含是从以前的包含中取消一些符号(包括包含警戒)。 考虑2个文件:
1.H:

 #define A 1 

2.h

 #undef A 

现在,按以下顺序:

 #include "1.h" #include "2.h" int B = A; 

将产生错误,因为A未定义。

以下顺序就好了:

 #include "1.h" #include "2.h" #include "1.h" int B = A; 

现在,如果1.h有包含警卫:

1.H:

 #ifndef GUARD_1 #define GUARD_1 #define A 1 #endif 

2.h可以做到:

 #undef GUARD_1 #undef A 

并产生同样的效果。

现在到stdlib.h 。 您可以在xh标题中组合这样的内容:

 #undef _STDLIB_H // Kill the include guard of stdlib.h #undef NULL // Undefine some important symbol from stdlib.h 

现在,这个序列:

 #include  #include "xh" 

NULL定义为NULL

还有这个:

 #include  #include "xh" #include  

将它定义。

虽然不能直接应用于 ,但有两次包含用户定义的头文件的原因:测试是否包含头文件两次会产生问题。

示例:考虑一对文件foo.hfoo.c声明并实现一堆foo_函数,定义,类型等。

文件foo.c

 #include "foo.h" #include "foo.h" rest of foo.c code ... 

第二次调用包含文件不应该导致问题, foo.c测试它。
OTOH, foo.c没有测试是否只包含头文件一次就可以了。