Search code examples
clinuxgccinclude-path

C Pre-Processor include-path order


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)


Solution

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