一、数据流分析
看一个例子
int getNumber(int x)
{
int n;
if (x > 0)
n = 1;
else if (x< 0)
n = -1;
return n;
}
上面的例子,有个问题,当x = 0的时候,将会出错;但是在使用gcc一般编译的情况下是不会报错的
gcc -Wall -c test.c
只有当使用优化处理参数,它就会提示错误
gcc -Wall -O2 -c test.c
uninit.c: In function ‘sign’:
uninit.c:3: warning: ‘s’ may be used uninitialized in this function
当打开优化开关后,它会做数据流分析;所以我们优化的时候使用-O参数可以找出隐藏比较深的参数
在这里有一点需要记住:思路越简单,代码越少,最容易看懂就是最好的程序
二、gcc编译c++程序
gcc是c++最好的编译器,它直接将c++转化成汇编语言;
gcc提供了gcc和g++两个不同的程序,但是gcc主要是对c语言,g++是对C++;gcc和g++都是外壳,它们的选项基本是一致的
#include <iostream>
int main()
{
std::cout << "Hello World" <<std::endl;
return 0;
}
gcc -Wall hello.cc -o hello // 报错:gcc: error trying to exec 'cc1plus': execvp: No such file or directory
g++ -Wall hello.cc -o hello
三、一个重点基本知识,编译原理,编译器是怎么工作的
有四个处理过程
- Preprocessing预处理,去调用cpp扩展宏
- Complation编辑阶段,将c的源程序编译为汇编语言
- Assembly将汇编语言编译为机器吗,产生目标文件
- Linking创建可执行的目标文件(这里要包含运行库,标准库)
我们从一个hello.c看上面四个步骤
#include <stdio.h>
int main(void)
{
print_r("Hello World!\n");
return 0;
}
第一步、预处理
cpp hello.c > hello.i // 把程序所有的宏都扩展开了
第二步、编译阶段
gcc -Wall -S hello.i // 只是把hello.i转换为汇编语言;编译器最复杂的工作
第三步、汇编器
as hello.s -o hello.o
第四步、连接
上面的代码中,printf是外部的,必须经过外部的连接才能使用
gcc hello.o