有人有两次包含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.h
和foo.c
声明并实现一堆foo_
函数,定义,类型等。
文件foo.c
#include "foo.h" #include "foo.h" rest of foo.c code ...
第二次调用包含文件不应该导致问题, foo.c
测试它。
OTOH, foo.c
没有测试是否只包含头文件一次就可以了。