LinuxC++开发记录(g++)

匿名 (未验证) 提交于 2019-12-02 21:56:30

g++使用

1. 编译过程

  • 预处理(-E)
  • 编译(-S)
  • 汇编(-c)
  • 链接(-O)

1.1 预处理(-E)

为了直观的了解预处理,理解预处理做了哪些工作,不说那么多,直接上代码,创建main.h与main.cpp文件,有头文件引用,有宏定义,有注释,还有未定义参数赋值的错误。代码如下:

/* main.h */ #define VALUES 100 int test();  void test2(){}  void test3(){}  void test4(){}
/* main.cpp */ #include <main.h>  int main() {     // 参数未定义     a = 100;     return test(); }  int test() {     return VALUES; }

预处理:

g++ -E main.cpp -I. > main.i

main.i为:

# 1 "main.cpp" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "main.cpp" # 1 "./main.h" 1  int test();  void test2(){}  void test3(){}  void test4(){} # 2 "main.cpp" 2  int main() {      a = 100;     return test(); }  int test() {     return 100; }

生成很顺利,可以看出,预处理工作:

  1. 不关注语法错误
  2. 宏替换
  3. 消除注释
  4. 将头文件整个包括进来,连空行都是完整的复制过来的

1.2 编译(-S)

编译将会把预处理生成的.i文件生成为.s的汇编代码文件。
继续上面的代码,当我们尝试编译上面生成的main.i文件时,会提示语法错误:

g++ -S main.i
main.cpp: In function ‘int main()’: main.cpp:6:5: error: ‘a’ was not declared in this scope      a = 100;

我们在main.c中加入int a;

g++ -E main.cpp -I. > main.i g++ -S main.i

这样就可以通过编译,默认生成main.s汇编文件,打开如下:

    .file    "main.cpp"     .text     .globl    _Z5test2v     .type    _Z5test2v, @function _Z5test2v: .LFB0:     .cfi_startproc     pushq    %rbp     .cfi_def_cfa_offset 16     .cfi_offset 6, -16     movq    %rsp, %rbp     .cfi_def_cfa_register 6     nop     popq    %rbp     .cfi_def_cfa 7, 8     ret     .cfi_endproc .LFE0:     .size    _Z5test2v, .-_Z5test2v     .globl    _Z5test3v     .type    _Z5test3v, @function _Z5test3v: .LFB1:     .cfi_startproc     pushq    %rbp     .cfi_def_cfa_offset 16     .cfi_offset 6, -16     movq    %rsp, %rbp     .cfi_def_cfa_register 6     nop     popq    %rbp     .cfi_def_cfa 7, 8     ret     .cfi_endproc .LFE1:     .size    _Z5test3v, .-_Z5test3v     .globl    _Z5test4v     .type    _Z5test4v, @function _Z5test4v: .LFB2:     .cfi_startproc     pushq    %rbp     .cfi_def_cfa_offset 16     .cfi_offset 6, -16     movq    %rsp, %rbp     .cfi_def_cfa_register 6     nop     popq    %rbp     .cfi_def_cfa 7, 8     ret     .cfi_endproc .LFE2:     .size    _Z5test4v, .-_Z5test4v     .globl    main     .type    main, @function main: .LFB3:     .cfi_startproc     pushq    %rbp     .cfi_def_cfa_offset 16     .cfi_offset 6, -16     movq    %rsp, %rbp     .cfi_def_cfa_register 6     subq    $16, %rsp     movl    $100, -4(%rbp)     call    _Z4testv     leave     .cfi_def_cfa 7, 8     ret     .cfi_endproc .LFE3:     .size    main, .-main     .globl    _Z4testv     .type    _Z4testv, @function _Z4testv: .LFB4:     .cfi_startproc     pushq    %rbp     .cfi_def_cfa_offset 16     .cfi_offset 6, -16     movq    %rsp, %rbp     .cfi_def_cfa_register 6     movl    $100, %eax     popq    %rbp     .cfi_def_cfa 7, 8     ret     .cfi_endproc .LFE4:     .size    _Z4testv, .-_Z4testv     .ident    "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609"     .section    .note.GNU-stack,"",@progbits

从这开始就和汇编是一样的了,再深入就需要去了解汇编的原理,后面两个过程不再详细描述。

1.3 汇编(-c)

汇编的工作是将汇编代码转成机器代码,注意“-c”是小写字母,而预处理和编译都是大写字母。汇编后生成.o目标文件。

g++ -c main.i

生成main.o

1.4 链接(-o)

将.o、.a、.so等文件链接生成可执行文件。

g++ main.o -o main

生成main可执行文件

g++ main.o

生成默认的a.out可执行文件

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!