While looking at gcc preprocessor output on a file #include
-ing a system header, I noticed that linemarkers contained flags 3
, or 4
, respectively (I found it the definition here: [1]):
3 This indicates that the following text comes from a system header file, so certain warnings should be suppressed.
4 This indicates that the following text should be treated as being wrapped in an implicit extern "C" block.
tl;dr:
What is the role of these flags in the compilation/linking (if any) process? Since they are voluntary and may be omitted (
-P
) or stripped, they cannot be relied upon during compilation; so what purpose do these flags serve? Also it would seem that clang does not emit them at all.How is a flag (
3
or4
) determined? Is it based on a path substring match? If so, how/where are these paths defined?
I was curious about flag 4
in particular, so I tried to find out how is a header file marked with a flag 4
and what consequences it will have (e.g., what is the scope of this extern "C"
block?). Thus, I created a testing header and a minimal program [2], moved the testing header around. Running gcc -E
on the program using the header shows two different flags used, depending on location:
# 1 "/usr/include/header.h" 1 4
# 1 "/usr/include/c++/9/header.h" 1 3
This would seem to indicate that the flag is determined based on path. Is that so?
There was no extern "C"
inserted anywhere, so I decided to determine the scope of extern "C"
. Compiled it with g++ -xc++ -std=c++0x test.cc -O0 -g3 -ffunction-sections -c
, but the resulting ELF file had function names mangled, allowed for multiple function definitions -- things that naturally cannot occur with extern "C"
.
[1] https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
[2]
/* /usr/include/header.h */
int foo(int){ ... }
/* test.cc */
#include <header.h>
int main(int argc, const char **argv) { return foo(argc); }