我的系统上有几个副本,比如stddef.h
,一个位于/usr/include/linux/stddef.h
路径中,看起来像这样:
#ifndef _LINUX_STDDEF_H
#define _LINUX_STDDEF_H
#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
另一个位于/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/include/
路径中,这就是我说#include <stddef.h>
时使用的那个。该内容与第一个内容有很大不同,包含ptrdiff_t
,size_t
等的定义。
我的问题是:据我所知,C / C ++标准要求size_t
的定义应放在stddef.h
中,但第一个定义不符合stddef.h
。那个显然不是C / C ++标准提到的那个。如果该文件出于其他目的,为什么这两个文件都被命名为{{1}},如果它们有不同的名称,它们会不会更安全/更清晰?
答案 0 :(得分:3)
linux内核不与c标准库链接,因此 - 作为一般规则 - 标准包含文件不能安全使用,因此linux内核使用自己的包含文件,这些文件已知不依赖于c库函数或数据。
任何要在内核空间中运行的软件 - 例如内核模块 - 都应该使用include / linux文件而不是标准库文件。
显然,内核包含文件只包含内核中可能需要的内容,因此只是标准c包含文件的一小部分。
答案 1 :(得分:0)
C标准要求包含stddef.h
足以定义size_t
。在引擎盖下,它可以布局,但图书馆实施者希望。
你会在linux中看到很多,主要是因为系统之间的许多实现不同(例如x86与arm),并且最容易将特定版本放在单独的目录中。
注意:但是,在/usr/include/linux/stddef.h
的特定情况下,这是一个内核头(用于编译内核)。这并不打算包含在用户空间源代码中。
此编辑是回复shinkou的评论。我不知道如何进行多行注释,所以这是最简单的方法:
$ cat incltest.c
#include <stddef.h>
$ cpp -H incltest.c
...
. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h
...
您可以为任何标题执行此操作。
通常,如果您的系统上有多个版本的GCC,您将拥有多个版本的cpp(因此您可以看到不同编译器使用不同版本):
$ cpp-4.4 -H incltest.c
. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.4.5/include/stddef.h
答案 2 :(得分:0)
我认为一个与GCC标准头相关,另一个与内核特定定义有关。所以内容在不同的范围内有不同的目的。