首页
导航
博客
电子书
算法
众创
代码
随贴
关于我们
您好,欢迎来到码863代码分享网! 请
[登录]
/
[注册]
搜 索
标题:
*
140
字
TAG标签:
(用空格隔开)
30
字
恢复历史版本:
请选择分类
html
python
javascript
php
sql
c
c++
c#
java
plain
所有人可见
仅自己可见
编辑器:UEditor
编辑器:TinyMCE
编辑器:Editor.md
HTML转MD
HTML转MD2
<p>一、编译的四个阶段</p> <ol class="list-paddingleft-2"> <li> <p>预处理:编译处理宏定义等宏命令(eg:#define)&mdash;&mdash;生成后缀为&ldquo;.i&rdquo;的文件 </p> </li> <li> <p>编译:将预处理后的文件转换成汇编语言&mdash;&mdash;生成后缀为&ldquo;.s&rdquo;的文件 </p> </li> <li> <p>汇编:由汇编生成的文件翻译为二进制目标文件&mdash;&mdash;生成后缀为&ldquo;.o&rdquo;的文件 </p> </li> <li> <p>连接:多个目标文件(二进制)结合库函数等综合成的能直接独立执行的执行文件&mdash;&mdash;生成后缀为&ldquo;.out&rdquo;的文件</p> </li> </ol> <p>在我们理解了上述四个流程后,我们在关注gcc和g++在流程上的区别。</p> <p>gcc无法进行库文件的连接,即无法编译完成步骤4;而g++则能完整编译出可执行文件。(实质上,g++从步骤1-步骤3均是调用gcc完成,步骤4连接则由自己完成)</p> <p> </p> <p>二、gcc 与g++的区别</p> <pre class="language-markup"><code>首先说明:gcc 和 GCC 是两个不同的东西 GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。 gcc是GCC中的GUN C Compiler(C 编译器) g++是GCC中的GUN C++ Compiler(C++编译器)</code></pre> <p> </p> <p><strong>误区一:gcc只能编译C代码,g++只能编译c++代码。</strong></p> <p>事实上,二者都可以编译c或cpp文件。</p> <p>gcc和g++的主要区别</p> <ol class="list-paddingleft-2"> <li> <p>对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(cpp的语法规则比c的更强一些)</p> </li> <li> <p>对于 .c和.cpp文件,g++则统一当做cpp文件编译</p> </li> </ol> <p><strong>误区二:编译只能使用gcc,连接只能使用g++</strong></p> <p>这句话混淆了概念。编译可以用 gcc 或 g++,而链接可以用 g++ 或者 gcc-lstdc++。</p> <p>因为 gcc 命令不能自动和 C++ 库链接,所以通常使用 g++ 来完成链接。</p> <p>但在编译阶段,g++ 会自动调用 gcc,二者等价。</p> <p>在编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接统统用g++了,这就给人一种错觉,好像cpp程序只能用g++似的。</p> <p> </p> <p><strong>误区三:extern &ldquo;C&rdquo; 与 gcc/g++ 有关系</strong></p> <p>实际上并无关系,</p> <p>无论是 gcc 还是 g++,用 extern &ldquo;c&rdquo; 时,都是以 C 的命名方式来为symbol 命名,</p> <p>否则,都以 C++ 方式为函数命名。</p> <p> </p> <p>这里以reciprocal.cpp为例:</p> <pre class="language-cpp"><code>#include <cassert> #include "reciprocal.hpp" double reciprocal (int i) { // I should be non-zero. assert (i != 0); return 1.0/i; }</code></pre> <p>1) 未加 extern &ldquo;c&rdquo;时,reciprocal.hpp代码为:</p> <pre class="language-cpp"><code> //一段代码 extern double reciprocal (int i);</code></pre> <p> </p> <p>命令:</p> <p>g++ -S reciprocal.cpp</p> <p>less reciprocal.s</p> <p>使用gcc和g++编译运行结果:</p> <p> <img style="color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;border:0px none;margin:0px;" title="" src="https://img-blog.csdn.net/20180507115853334?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM0NTcxNjc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="" /></p> <p> </p> <p>未加extern “C”时,函数reciprocal用gcc和g++编译得到的函数名是一样的,都是以C++的命名方式。</p> <p>2) 加 extern “c”时,reciprocal.hpp代码为:</p> <pre class="brush:cpp;toolbar:false">extern "C" { //一段代码 extern double reciprocal (int i); }</pre> <p> </p> <p> </p> <p>使用gcc和g++编译运行结果:</p> <p> <img style="border:0px none;margin:0px;color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;white-space:normal;background-color:#ffffff;" title="" src="https://img-blog.csdn.net/20180507120026840?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTM0NTcxNjc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述" /></p> <p>也就是说,添加extern “C”后,函数reciprocal用gcc和g++编译得到的函数名是一样的,都是以C的命名方式。</p> <p>由此可见,extern “C”与采用gcc/g++并无关系。</p> <p> </p> <p><strong>误区四:gcc不会定义__cplusplus宏,而g++会</strong></p> <p>实际上,这个宏只是标志着编译器将会把代码按C还是C++语法来解释,如上所述,如果后缀为.c,并且采用gcc编译器,则该宏就是未定义的,否则,就是已定义。</p> <p> </p> <p>gcc在编译.c文件时,可使用的预定义宏是比较少的,很多都是未定义的。</p> <p>gcc在编译cpp文件时、g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下:</p> <pre class="brush:cpp;toolbar:false">#define __GXX_WEAK__ 1 #define __cplusplus 1 #define __DEPRECATED 1 #define __GNUG__ 4 #define __EXCEPTIONS 1 #define __private_extern__ extern</pre> <p> </p> <p>因此,我们总是会看到如下格式的代码(功能是对编译器提示使用C的方式来处理函数):</p> <p><span style="color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;background-color:#ffffff;">其中,__cplusplus是c++定义的宏,如果</span><span style="font-weight:bold;color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;background-color:#ffffff;">gcc在编译cpp文件时、g++在编译c文件和cpp文件</span><span style="color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;background-color:#ffffff;">时,extern c声明会有效。如果是</span><span style="font-weight:bold;color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;background-color:#ffffff;">gcc在编译.c文件</span><span style="color:#4d4d4d;font-family:'-apple-system', 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;background-color:#ffffff;">时,那么,extern c声明无效。</span></p> <pre class="brush:cpp;toolbar:false">#ifdef __cplusplus extern "C" { #endif //一段代码 #ifdef __cplusplus } #endif</pre> <p>为什么需要使用extern “C”呢?C++之父在设计C++之时,考虑到当时已经存在了大量的C代码,为了支持原来的C代码和已经写好C库,需要在C++中尽可能的支持C,而extern “C”就是其中的一个策略。</p> <p> </p> <p>试想这样的情况:一个库文件已经用C写好了而且运行得很良好,这个时候我们需要使用这个库文件,但是我们需要使用C++来写这个新的代码。如果这个代码使用的是C++的方式链接这个C库文件的话,那么就会出现链接错误。</p> <p> </p> <p>C和C++对函数的处理方式是不同的。extern“C”是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern “C”来说明。</p> <p> </p>
CopyRight 2002~2023 精通2100网 联系邮箱:qqtxt@163.com
版权所有:精通2100网
湘ICP备2023018646号-1
MYSQl共执行 4 个查询,用时 0.0017540454864502 秒,PHP脚本用时 0.003980 秒,占用内存 0.535 MB,Gzip 已启用