0

I typed "cpp -v" on linux and it resulted:

#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

So I searched in that order for stdio.h, like the CPP would do, and I firstly found it at "/usr/include/x86_64-linux-gnu". Specifically, its full path is "/usr/include/x86_64-linux-gnu/bits/stdio.h"

BUT when I opened the file, it clearly states on 21-23 lines:

#ifndef _STDIO_H
# error "Never include <bits/stdio.h> directly; use <stdio.h> instead."
#endif

So, in theory when I type in my C source code:

#include <stdio.h>

The pre-processor finds it at "/usr/include/x86_64-linux-gnu/bits/stdio.h", and includes it. How is that possible? Is there a mechanism that makes the CPP ignore the "./bits/stdio.h"? Or is my theory wrong?

//I work on Ubuntu 18, I have also clang installed (don't know if it matters)

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
mark_infinite
  • 383
  • 1
  • 7
  • 13
  • 4
    `/usr/include/x86_64-linux-gnu/bits/` is not in the list of the search paths. To include that file one would need to do `#include ` – kaylum Jan 03 '20 at 21:11
  • You could find the actual header being included by looking [here](https://stackoverflow.com/questions/5834778/how-to-tell-where-a-header-file-is-included-from) – Tony Tannous Jan 03 '20 at 21:12
  • 1
    You can use `gcc -H …` to see the headers actually included by a compilation. – Jonathan Leffler Jan 03 '20 at 21:40

1 Answers1

4

No, it does not find /usr/include/x86_64-linux-gnu/bits/stdio.h.

Include directories are not searched recursively.

Based on the output from your question GCC will search for #include<stdio.h> with the following paths

/usr/lib/gcc/x86_64-linux-gnu/7/include/stdio.h
/usr/local/include/stdio.h
/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/stdio.h
/usr/include/x86_64-linux-gnu/stdio.h
/usr/include/stdio.h

in that order. Nothing more.

Since /usr/include/x86_64-linux-gnu/stdio.h doesn't exist, it can't be used.

Only (most likely) when looking for /usr/include/stdio.h, it will find a file and use that.


This is also what the error message you are referring to indicates. If you did #include<bits/stdio.h>, it would look for /usr/include/x86_64-linux-gnu/bits/stdio.h and use it. The error message is there to make sure that a user will not able to use such an include, because that file is an implementation detail of the standard library that should not be used by user code.

walnut
  • 21,629
  • 4
  • 23
  • 59