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