Why do different headers have the same name?

I have several copies of, let's say, stddef.h on my system, one is in the path /usr/include/linux/stddef.h , and looks like this:

#ifndef _LINUX_STDDEF_H
#define _LINUX_STDDEF_H

#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

#endif

Another one is in the path /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/include/ , and that is the one which is used when I say #include <stddef.h> . That one's contents are a lot different from the first one, contains the definitions of ptrdiff_t , size_t etc.

My question is: As far as I know, the C/C++ standards require that the definition of size_t should be placed in stddef.h , however the first one doesn't follow that. That one clearly isn't the one mentioned by the C/C++ standards. If that file is there on for some other purpose, why are both of these files named as stddef.h , wouldn't it be safer/more clear if they had different names?


The linux kernel does not link with the c standard library, therefore - as a general rule - the standard include files cannot be used safely, so the linux kernel uses its own include files which are known not to rely on c library functions or data.

Any software that is to run in kernel space - such as kernel modules - should use the include/linux files and not the standard library ones.

Obviously the kernel include files only cover things that are likely to be needed in the kernel so are a very small subset of the standard c include files.


i think one is related to GCC standerd header and another is related to kernel specific definition. So the contents are different with same purpose in different scope.


The C standard requires that including stddef.h is sufficient for defining size_t . Under the hood, it can be laid out however the library implementers wish.

You will see this a lot in linux, primarily because a lot of the implementations differ between systems (eg x86 vs arm), and its easiest to put the specific version in a separate directory.

Note: However, in the specific case of /usr/include/linux/stddef.h , this is a kernel header (meant for compiling the kernel). This was not intended to have been included in userspace source code.


This edit is to reply to shinkou's comment. I dont know how to do multiline comments, so this is the easiest way:

$ 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
...

You can do this for any header.

Generally, if you have multiple versions of GCC on your system, you will have multiple versions of cpp (and hence you can see that different versions are used by different compilers):

$ cpp-4.4 -H incltest.c 
. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.4.5/include/stddef.h
链接地址: http://www.djcxy.com/p/8668.html

上一篇: 将映射关系映射到数组索引

下一篇: 为什么不同的标题具有相同的名称?