Compilers - BruceDai003/tech_blog GitHub Wiki

ABI

发现编译有的时候会加上一个选项:-D_GLIBCXX_USE_CXX11_ABI=0,搜了一下,找到GCC C++ Dual ABI。是编译器版本不同的话,比如gcc从4.9到5.1版本,里面的ABI(application binary interface)有比较大的变动。如果部分代码是用以前的4.9版本编译的,现在转成5.1版本编译,ABI的不同会造成在链接的时候符号不同,报错。所以,通过指定-D_GLIBCXX_USE_CXX11_ABI=0,可以使得gcc使用旧的ABI来编译。 通过添加这个选项可以解决比如如下的问题:

 .../extensions.hpp(38): error: “std::list” is ambiguous

当然了,不一定是std::list

因为C++的编译器会对所有extern "C++"的符号名字进行名字重整,而怎么重整(name mangling)取决于编译器自身的算法。而ABI要用到这些重整后的名字来把库和编译的代码链接到一起。ABI有时候会变化,所以会导致名字不一致。

编译器优化技术之常量折叠

参见https://zh.m.wikipedia.org/zh/%E5%B8%B8%E6%95%B8%E6%8A%98%E7%96%8A

  • 常量折叠(constant folding):编译期将常量数值计算出来,通常会在IR tree中进行。
  • 常量传播(constant propagation):替代expression中已知常量的过程。常数传播在编译器中使用定义可达性(Reaching definition)分析实作,如果一个变数的所有定义可达性,都是赋予相同的数值,那么这个变数将会是一个常数,而且会被常数取代。
  • 稀疏有条件常量传播(sparse conditional constant propagation):根据条件if-else的状态是否是确定的选择合适的分支,从而进一步简化代码。

ubuntu中不同gcc切换

参见https://www.jianshu.com/p/f66eed3a3a25 首先

ll /usr/bin/gcc*

查看当前gcc有哪些版本。 比如安装gcc-4.8, gcc-5

sudo apt install gcc-4.8 gcc-4.8-multilib g++-4.8 g++-4.8-multilib
sudo apt install gcc-5 gcc-5--multilib g++-5 g++-5--multilib

然后使用update-alternatives来设置不同版本的优先级: update-alternatives是ubuntu系统中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令、哪个软件版本。 以我们通常的gcc 7.5.0 以及gcc 9.4.0为例:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 75 --slave /usr/bin/g++ g++ /usr/bin/g++-7
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 94 --slave /usr/bin/g++ g++ /usr/bin/g++-9

(Optional)选择当前gcc版本

sudo update-alternatives --config gcc

验证

gcc -v

删除某个版本:

sudo update-alternatives --remove gcc /usr/bin/gcc-4.5