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

时间:2016-07-21 12:54:17

标签: c

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

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

我注意到包含已定义stdlib.h两次(更新:评论是我的):

#include <termios.h>
#include <stdlib.h> // first time
#include <stdio.h> 
#include <errno.h>
#include <string.h>
#include <stdlib.h>  // second time
#include <ctype.h> 

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

5 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

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

关于此的C standard says以下内容:

  

标准标题可以包含在任何顺序中;每个都可以包括在内   在给定范围内不止一次,没有效果   仅包含一次,但包含sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', DEST_PORT)) sock.setsockopt(socket.IPPROTO_IPV6, socket.IP_HDRINCL, 1) 的效果除外   取决于<assert.h>的定义。

答案 2 :(得分:2)

没有理由两次包含特定的头文件。如果文件具有适当的包含保护,则第二个包含将不起作用。如果它没有包含保护,那么对于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以正确管理其特定于操作系统的包含文件而闻名。如果你以错误的顺序包含它们,你将会遇到很多错误。

答案 3 :(得分:1)

它可以产生影响的唯一情况是,其中一个包含取消定义来自先前包含的某些符号(包括包含警戒)。考虑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。您可以在 x.h 标题中撰写类似的内容:

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

现在,这个序列:

#include <stdlib.h>
#include "x.h"

NULL未定义

而且:

#include <stdlib.h>
#include "x.h"
#include <stdlib.h>

将定义它。

答案 4 :(得分:0)

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

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

档案foo.c

#include "foo.h"
#include "foo.h"

rest of foo.c code ...

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