7

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?

5
  • That looks rather fishy, and the qualified guard word would seem to imply that it's not intentionally masquerading as stddef.h. Can you check which package it comes from? Commented Jul 19, 2011 at 2:56
  • @Cheezmeister: apt-file yields: linux-libc-dev: /usr/include/linux/stddef.h and gcc-4.5: /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/include/stddef.h Commented Jul 19, 2011 at 3:11
  • @Cheezmeister. I second you. Neither the pathname /usr/include/linux/stddef.h implies it's the standard header. There is no stddef.h under /usr/include in my copy of Linux (Slackware64 13). Commented Jul 19, 2011 at 3:12
  • 1
    /usr/include/linux are kernel headers. the glibc headers are placed in separate directories for each version of glibc installed on the system. Commented Jul 19, 2011 at 3:20
  • 1
    @shinkou: Yes, I am aware that the first one isn't the standard one. However, why did the kernel developers decide to name their header file with a standard one? Wouldn't it be a better choice if developers name their headers differently from the standard ones so that talking about x.h does not create ambiguities? Commented Jul 19, 2011 at 3:40

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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 

4 Comments

That's what I understand, too. However, could you explain why /usr/include/stddef.h does not exist (in some of the distros. e.g. Slackware)?
If a distribution is to allow multiple libc distributions (and, therefore, multiple versions of stddef.h), how would you implement it? You would probably put it in different directories. GCC keeps it in separate directories, and the compiler automatically adds the version-specific headers in a predetermined directory. -- Just checked, cpp -H will tell you which header is used
If /usr/include/linux/stddef.h is for the use of kernel compilation only, where can we find the real stddef.h for the userspace then? find /usr/include -type f -name stddef.h only returns /usr/include/linux/stddef.h on my machine.
I haven't figured out how to use new-lines in comments yet, so I'm just going to post another answer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.