gcc中的预处理得到的.i文件的内容

gcc 预处理后的.i文件内每一行所表达的意思是什么?
#1 是什么意思? “srcf_inclusion.c”是什么? 为什么又重复了一遍 。built_in>是什么? /usr/include/stdc-predef.h是什么? 后面的 1 3 4 又表达什么? command-line是什么? 后面的 2 是什么?#2又是什么? 为什么有的是”“ 有的是 <>?
求解答,请详细解答。

gcc -E srcf_inclusion.c -o srcf_inclusion.i
srcf_inclusion.i:
#  1  "srcf_inclusion.c"
#  1  "<built-in>"
#  1  "/usr/include/stdc-predef.h"  1  3  4
#  1  "<command-line>"  2
#  1  "srcf_inclusion.c"
#  1  "srcf_inclusion.h"  1
int a;

int b;
#  2  "srcf_inclusion.c"  2
int main(int argc, char *argv[])
{
  prinf("Joran\n");
  return 0;
}

可采纳

gcc - E srcf_inclusion.c - o srcf_inclusion.i
srcf_inclusion.i:
#  1  "srcf_inclusion.c"        //# 行号 "源文件名",表示源文件的第一行,文件名为srcf_inclusion.c。
#  1  "<built-in>"                //# 行号 "",表示编译器内建的头文件。
#  1  "/usr/include/stdc-predef.h"  1  3  4  //# 行号 "文件名" 行号 "标识符",表示头文件包含,其中“ / usr / include / stdc - predef.h”是系统自带的头文件。
#  1  "<command-line>"  2   //来自命令行的代码。
#  1  "srcf_inclusion.c"        //# 行号 "源文件名" 
#  1  "srcf_inclusion.h"  1        //# 行号 "头文件名",表示#include指令包含的头文件“srcf_inclusion.h”。
int a;

int b;
#  2  "srcf_inclusion.c"  2
int main(int argc, char* argv[])
{
    prinf("Joran\n");
    return 0;
}
```c++

srcf_inclusion.i中每一行所表达的意思如下:

  1. 第一行:# 行号 "源文件名",表示源文件的第一行,文件名为srcf_inclusion.c。
  2. 第二行:# 行号 "",表示编译器内建的头文件。
  3. 第三到六行:# 行号 "文件名" 行号 "标识符",表示头文件包含,其中“/usr/include/stdc-predef.h”是系统自带的头文件。
  4. 第七行:# 行号 "",表示指令行参数。
  5. 第八到十行:# 行号 "源文件名" 行号 "头文件名",表示#include指令包含的头文件“srcf_inclusion.h”。
  6. 第十一行:int a;,表示源代码中的变量定义。
  7. 第十三到十四行:int b;,表示源代码中的另一个变量定义。
  8. 第十五到十七行:# 行号 "源文件名" 行号 "行号",表示源代码中的main函数,其中第二个行号2表示在源文件的第2行定义了main函数。
  9. 第十八到二十行:main函数的实现代码,其中包含一条printf函数的调用语句。
    通过查看源文件和预处理后的.i文件可以对程序中的宏和文件包含进行全面的了解,并且也可以帮助进行调试和代码优化。

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 1 3 4
# 33 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 424 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 427 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 428 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4
# 429 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 425 "/usr/include/features.h" 2 3 4
# 448 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 449 "/usr/include/features.h" 2 3 4
# 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4





# 1 "/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h" 1 3 4
# 216 "/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h" 3 4

# 216 "/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 34 "/usr/include/stdio.h" 2 3 4

# 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4
# 27 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4


typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;


typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;

typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;






typedef long int __quad_t;
typedef unsigned long int __u_quad_t;







typedef long int __intmax_t;
typedef unsigned long int __uintmax_t;
# 130 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4
# 131 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4


typedef unsigned long int __dev_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef unsigned long int __ino_t;
typedef unsigned long int __ino64_t;
typedef unsigned int __mode_t;
typedef unsigned long int __nlink_t;
typedef long int __off_t;
typedef long int __off64_t;
typedef int __pid_t;
typedef struct { int __val[2]; } __fsid_t;
typedef long int __clock_t;
typedef unsigned long int __rlim_t;
typedef unsigned long int __rlim64_t;
typedef unsigned int __id_t;
typedef long int __time_t;
typedef unsigned int __useconds_t;
typedef long int __suseconds_t;

typedef int __daddr_t;
typedef int __key_t;


typedef int __clockid_t;


typedef void * __timer_t;


typedef long int __blksize_t;




typedef long int __blkcnt_t;
typedef long int __blkcnt64_t;


typedef unsigned long int __fsblkcnt_t;
typedef unsigned long int __fsblkcnt64_t;


typedef unsigned long int __fsfilcnt_t;
typedef unsigned long int __fsfilcnt64_t;


typedef long int __fsword_t;

typedef long int __ssize_t;


typedef long int __syscall_slong_t;

typedef unsigned long int __syscall_ulong_t;



typedef __off64_t __loff_t;
typedef char *__caddr_t;


typedef long int __intptr_t;


typedef unsigned int __socklen_t;




typedef int __sig_atomic_t;
# 36 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__FILE.h" 1 3 4



struct _IO_FILE;
typedef struct _IO_FILE __FILE;
# 37 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/FILE.h" 1 3 4



struct _IO_FILE;


typedef struct _IO_FILE FILE;
# 38 "/usr/include/stdio.h" 2 3 4



# 1 "/usr/include/x86_64-linux-gnu/bits/libio.h" 1 3 4
# 35 "/usr/include/x86_64-linux-gnu/bits/libio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/_G_config.h" 1 3 4
# 19 "/usr/include/x86_64-linux-gnu/bits/_G_config.h" 3 4
# 1 "/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h" 1 3 4
# 20 "/usr/include/x86_64-linux-gnu/bits/_G_config.h" 2 3 4

# 1 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 1 3 4
# 13 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 3 4
typedef struct
{
  int __count;
  union
  {
    unsigned int __wch;
    char __wchb[4];
  } __value;
} __mbstate_t;
# 22 "/usr/include/x86_64-linux-gnu/bits/_G_config.h" 2 3 4




typedef struct
{
  __off_t __pos;
  __mbstate_t __state;
} _G_fpos_t;
typedef struct
{
  __off64_t __pos;
  __mbstate_t __state;
} _G_fpos64_t;
# 36 "/usr/include/x86_64-linux-gnu/bits/libio.h" 2 3 4
# 53 "/usr/include/x86_64-linux-gnu/bits/libio.h" 3 4
# 1 "/usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h" 1 3 4
# 40 "/usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 54 "/usr/include/x86_64-linux-gnu/bits/libio.h" 2 3 4
# 149 "/usr/include/x86_64-linux-gnu/bits/libio.h" 3 4
struct _IO_jump_t; struct _IO_FILE;




typedef void _IO_lock_t;





struct _IO_marker {
  struct _IO_marker *_next;
  struct _IO_FILE *_sbuf;



  int _pos;
# 177 "/usr/include/x86_64-linux-gnu/bits/libio.h" 3 4
};


enum __codecvt_result
{
  __codecvt_ok,
  __codecvt_partial,
  __codecvt_error,
  __codecvt_noconv
};
# 245 "/usr/include/x86_64-linux-gnu/bits/libio.h" 3 4
struct _IO_FILE {
  int _flags;




  char* _IO_read_ptr;
  char* _IO_read_end;
  char* _IO_read_base;
  char* _IO_write_base;
  char* _IO_write_ptr;
  char* _IO_write_end;
  char* _IO_buf_base;
  char* _IO_buf_end;

  char *_IO_save_base;
  char *_IO_backup_base;
  char *_IO_save_end;

  struct _IO_marker *_markers;

  struct _IO_FILE *_chain;

  int _fileno;



根据您提供的gcc预处理命令生成的.i文件内容,我将逐行解释每一行的意思:

  1. 第一行 "# 1 "srcf_inclusion.c"" 表示当前行是源文件 "srcf_inclusion.c" 的开始。
  2. 第二行 "# 1 """ 表示当前行是内置文件的开始。内置文件通常包含了一些编译器内部定义的宏和声明。
  3. 第三行 "# 1 "/usr/include/stdc-predef.h" 1 3 4" 表示当前行是"/usr/include/stdc-predef.h"文件的开始。其中的数字1、3、4是编译器的内部标记,可能表示不同的预处理状态或版本信息。
  4. 第四行 "# 1 "" 2" 表示当前行是命令行的开始,其中的数字2可能表示该行是通过命令行传递给编译器的参数。
  5. 第五行 "# 1 "srcf_inclusion.c"" 表示再次开始处理源文件 "srcf_inclusion.c"。
  6. 第六行 "# 1 "srcf_inclusion.h" 1" 表示当前行是头文件 "srcf_inclusion.h" 的开始。
  7. 接下来是一些变量的定义和函数的实现,不再具体解释。
  8. 最后一行 "# 2 "srcf_inclusion.c" 2" 表示当前行是源文件 "srcf_inclusion.c" 的结束。

至于"<>"和""之间的差异,通常在预处理过程中,使用""包围的是用户自定义的头文件,而使用<>包围的是系统提供的头文件。用户自定义的头文件通常位于当前目录或指定的搜索路径中,而系统头文件位于系统的标准库目录中。

希望以上解释对您有所帮助。如果您还有其他问题,请随时提问。

  1. 第一行指定了源文件的名称, "# 1"表示它是第一个指令,在后面可以用"#2", "#3"...依次表示后续指令。

  2. "# 1 """表示后面的代码是内置的代码。

  3. " /usr/include/stdc-predef.h" 是一个系统头文件,包含了对标准预定义宏的定义,标准预定义宏一般用来判断编译器和系统的类型。

  4. “1 3 4” 是对标准预定义宏的定义和赋值。