C++编译链接的那些小事
作者:网络转载 发布时间:[ 2014/1/24 9:58:13 ] 推荐标签:C++ 编译 链接
近,有同事向我多次问及C++关于编译链接方面的问题,包括如下:
1:什么样的函数以及变量可以定义在头文件中
2:extern "C"的作用
3:防止重复包含的宏的作用
4:函数之间是怎么链接起来的
我认为,这些问题不难,书上基本上都有,但要是没有真正思考过,凭死记硬背,也是只能“嘴上说说”而已,遇到问题还真棘手,所以我觉得有必要说一下。
C/C++的编译链接过程
其实,“编译”这个词大多数时候,我们指的是由一堆.h,.c,.cpp文件生成链接库或者可执行文件的过程。但是拿C/C++来说,其实这是很模糊的,由一堆C/C++文件生成应用程序包括预处理---编译文件---链接(写的比较粗糙,不影响本文论述)。
首先,要明白什么是编译单元,一个编译单元可以认为是一个.c或者.cpp文件,每一个编译单元首先会经过预处理得到一个临时的编译单元,这里称为tmp.cpp,预处理会把.c或者.cpp直接或者间接包含的其它文件(不只局限于.h文件,只要是#include即可)的内容替换进来,并展开宏调用等。
下面首先看一个例子:
a.h
#ifndef A_H_
#define A_H_
static int a = 1;
void fun();
#endif
a.cpp
[cpp] view plaincopy
#include "a.h"
static void hello_world()
{
}
只有a.h和a.cpp这两个文件,及其简单。首先通过g++的-E参数得到a.cpp预处理之后的内容
coderchen@coderchen:~/c++$ g++ -E a.cpp > tmp.cpp
查看tmp.cpp
# 1 "a.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.cpp"
# 1 "a.h" 1
static int a = 1;
void fun();
# 2 "a.cpp" 2
static void hello_world()
{
}
tmp.cpp是只经过预处理得到的文件,这个文件才是编译器能够真正看到的文件。这个过程是预处理。
其中#define A_H_的作用是防止重复包含a.h这个头文件,很多人都知道这一点,但是再仔细问,我见过大多数人都说不清楚。
这种宏是为了防止一个编译单元(cpp文件)重复包含同一个头文件。它在预处理阶段起作用,预处理器发现a.cpp内已经定义过A_H_这个宏的话,在a.cpp中再次发现#include "a.h"的时候不会把a.h的内容替换进a.cpp了。
编译器看到tmp.cpp的时候,会编译成一个obj文件,后由链接器对这一个对obj文件进行链接,从而得到可执行程序。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11