How to interpret #-prefixed lines in C preprocessor output?

前端 未结 1 1675
北海茫月
北海茫月 2021-01-15 08:17

The following is the code of hello.c :

#include 

int
main (void)
{
  printf (\"Hello, world!\\n\");
  return 0;
}

I used t

相关标签:
1条回答
  • 2021-01-15 08:45

    The fields of the preprocessor output are documented in 9 Preprocessor Output of the GNU cpp manual.

    The fields are:

    # linenum filename [flags]
    ...
    

    Such a line means that what follows it (...) originated at line number linenum in file filename. The optional flags are:-

    ‘1’

    This indicates the start of a new file.

    ‘2’

    This indicates returning to a file (after having included another file).

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

    You see that nesting arises from #include directives, e.g.

    # 1 "hello.c"
    # 1 "/usr/include/stdio.h" 1 3 4
    # 27 "/usr/include/stdio.h" 3 4
    # 1 "/usr/include/features.h" 1 3 4
    # 375 "/usr/include/features.h" 3 4
    # 1 "/usr/include/sys/cdefs.h" 1 3 4
    ...
    

    tells us:

    • At line #1 of "hello.c" start a new file "/usr/include/stdio.h",
    • at line #27 of which start another new file "/usr/include/features.h"
    • at line #375 of which start another new file "/usr/include/sys/cdefs.h"
    • ...

    It's not easy reading.

    The special "filenames" <built-in> and <command-line> will always crop up in a context resembling:-

    # 1 "hello.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 1 "<command-line>" 2
    # 1 "hello.c"
    

    at the top of the preprocessed output for any file. Details may vary with GCC version.

    As you'd guess, <built-in> and <command-line> are not real files. They are non-file sources of preprocessor tokens that need to be represented somehow in the output format, so they are treated as if they were files. Call them pseudo-files.

    <built-in> is the pseudo-file that contains the compiler's built-in macro definitions. For the way to see the contents of this pseudo-file, browse to GCC dump preprocessor defines.

    <command-line> is of course the preprocessor (usually GCC) commandline, considered as a source of macro definitions (and possibly un-definitions), e.g.

    gcc ... -DFOO=1 -UBAR ...
    

    So your example:

    # 1 "hello.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 1 "<command-line>" 2
    # 1 "hello.c"
    # 1 "/usr/include/stdio.h" 1 3 4
    ...
    

    represents this process:

    • Start reading hello.c, and then
    • immediately read the built-in macros pseudo-file, and then
    • immediately read the commandline pseudo-file, and then
    • immediately read the pre-defined macros file /usr/include/stdc-predef.h as if it was pre-included on the commandline by -include /usr/include/stdc-predef.h, and then
    • resume and finish reading the commandline pseudo-file, and then
    • resume reading hello.c, and then
    • start reading /usr/include/stdio.h
      ...
    0 讨论(0)
提交回复
热议问题