C++17引入的模块为什么能加快编译速度?


https://www.zhihu.com/question/37330979/answer/73595024


作者:hearts zh
链接:https://www.zhihu.com/question/37330979/answer/71692790
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

首先要说明的是,模块(module)在不同编程语言的并不完全一样,只是名字相同而已。查查英英词典,module: unit, part, component, segment, element。大概就是整体的一小部分的意思。软件里面一般指可以重用的部分。不同语言对于这个东西显然有不同的理解/定义。不细表。

要回答你的问题,首先要理解为啥c++编译慢呢?这要从C说起。C一开始采用了拷贝-插入模型。#include关键字,就是把另外一个文件原封不动的拷贝到现在的文件。为啥这样设计,我也不敢乱说,但这样设计,带来了一些常用的用法,这些用法在10多年前C++世界,甚至在现在的嵌入式世界,都蛮流行的。比如说,
//common.h
#define DEBUG

//main.c
#include "common.h"
#include "a.h"

int main() {
  #ifdef DEBUG
  debug_buffer[0] = 1;
  debug_print_buffer();
  #endif
  return 0;
}
  

//a.h
#include "common.h"
#ifdef DEBUG
extern int debug_buffer[10000000];
extern void debug_print_buffer();
#endif


//a.c
#include "a.h"
#ifdef DEBUG
int debug_buffer[10000000];
void debug_print_buffer() {}
#endif 


代码随便写的凑合着看,大概意思就酱。这种用法,只有拷贝-插入模式才有用。common里面的#define DEBUG影响了a.h,a.c和main.c。

当然也带来了一系列负面影响,例如如果a.h #include了common.h, b.h也#include了 common.h,如果a.h #include b.h的话呢,common.h就被拷贝插入了2次。不但影响编译速度,而且重复定义了common.h里面的东西。所以呢,对于c和c++来说,所有的.h里,都要写一些奇怪的东西防止被#include 2次。这大家都知道了,就不深入了。

以上为C。其实没有什么大问题。为什么到C++就变成问题了呢?这要从C/C++编译的另一面说起。从编译角度来讲,C/C++是每个.c, .cpp文件单独编译,最后放到一起链接。例如你有a.c和b.c,其实a.c和b.c是分别编译,最后放到一起连接成可执行文件或者库。

这其实是完全没问题的,因为分别编译好处是显而易见的,一旦b.c被更新了,a.c不需要重新编译一遍。加快了编译速度。

那你说有什么问题?问题就在c++中 .h 文件太长了!!特别是.h文件中还有模板!

对于C,.h文件无非就是函数声明之类的一些东西,但C++ .h文件是类,可以有类的成员定义,是模板,必须有模板的成员定义。

#include <iostream>根据某些实现,带来上万行的拷贝-插入,里面还全是模板。

假设a.cpp里有iostream,b.cpp里有iostream,因为分别编译,带来2万行的拷贝-插入。你有10000个.cpp文件就是10000*10000行的拷贝-插入重复编译。当然第一次编译很慢,之后因为你一般不会更新所有.cpp,会快一点,但也相当慢。

你说,为什么不把iostream编译一次,存起来,存到cache,其他的文件直接用?原因也很简单,不行!

iostream里面的具体实现,取决于include他的文件的环境。例如iostream里面有一个#ifdef DEBUG,那么#include <iostream>时,是否#define DEBUG取决了iostream里的东西并不一样。根本没法cache。

------------------------------------------------------------------

以上。那么module在C++中是什么?module的设计准则之一,就是module是独立的,不受import module的文件的环境影响。当然,module也不影响别人。于是编译好的module就可以被cache起来,具体编译器可以采用不同实现。可以cache到文件,内存,等等地方。

posted @ 2016-12-29 10:18  张同光  阅读(173)  评论(0编辑  收藏  举报