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