gcc和g++的区别。四个理解误区

本文澄清了gcc和g++在编译C/C++代码时的常见误解,包括它们的功能、链接过程、externC宏的作用及与gcc/g++的关系。通过实例展示了两者在编译阶段的等价性与链接阶段的分工。

原帖地址:

http://forum.byr.edu.cn/pc/pccon.php?id=1942&nid=56349

http://hi.baidu.com/walker20100000/blog/item/0be87acfa3852b0a01e928d4.html


gcc和g++的区别
 
  我们在编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而c++代码用g++,或者说编译用gcc,链接用g++,一时也不知哪个说法正确,如果再遇上个extern "C",分歧就更多了,这里我想作个了结,毕竟知识的目的是令人更清醒,而不是更糊涂。
 
误区一:gcc只能编译c代码,g++只能编译c++代码
两者都可以,但是请注意:
1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序;后缀为.cpp的,两者都会认为是c++程序,注意,虽然c++是c的超集,但是两者对语法的要求是有区别的,例如:
#include <stdio.h>
int main(int argc, char* argv[]) {
   if(argv == 0) return;
   printString( argv);
    return;
}
int printString(char* string) {
  sprintf(string, "This is a test.\n");
}
如果按照C的语法规则,OK,没问题,但是,一旦把后缀改为cpp,立刻报三个错:“printString未定义”;
“cannot convert `char**' to `char*”;
”return-statement with no value“;
分别对应前面红色标注的部分。可见C++的语法规则更加严谨一些。
2.编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接统统用g++了,这就给人一种错觉,好像cpp程序只能用g++似的。
 
误区二:gcc不会定义__cplusplus宏,而g++会
实际上,这个宏只是标志着编译器将会把代码按C还是C++语法来解释,如上所述,如果后缀为.c,并且采用gcc编译器,则该宏就是未定义的,否则,就是已定义。
 
误区三:编译只能用gcc,链接只能用g++
严格来说,这句话不算错误,但是它混淆了概念, 应该这样说:编译可以用gcc/g++,而链接可以用g++或者gcc -lstdc++。因为gcc命令不能自动和C++程序使用的库联接,所以通常使用g++来完成联接。但在编译阶段,g++会自动调用gcc,二者等价。
 
误区四:extern "C"与gcc/g++有关系
实际上并无关系,无论是gcc还是g++,用extern "c"时,都是以C的命名方式来为symbol命名,否则,都以c++方式命名。试验如下:
me.h
extern "C" void CppPrintf(void);
 
me.cpp:
#include <iostream>
#include "me.h"
using namespace std;
void CppPrintf(void)
{
     cout << "Hello\n";
}
 
test.cpp:
#include <stdlib.h>
#include <stdio.h>
#include "me.h"        
int main(void)
{
    CppPrintf();
    return 0;
}
 
1. 先给me.h加上extern "C",看用gcc和g++命名有什么不同
[root@root G++]# g++ -S me.cpp
[root@root G++]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   CppPrintf, @function
[root@root GCC]# gcc -S me.cpp
[root@root GCC]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   CppPrintf, @function
完全相同!
               
2. 去掉me.h中extern "C",看用gcc和g++命名有什么不同
[root@root GCC]# gcc -S me.cpp
[root@root GCC]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   _Z9CppPrintfv, @function
[root@root G++]# g++ -S me.cpp
[root@root G++]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   _Z9CppPrintfv, @function
完全相同!
【结论】完全相同,可见extern "C"与采用gcc/g++并无关系,以上的试验还间接的印证了前面的说法:在编译阶段,g++是调用gcc的。


<think>好的,我现在需要回答用户关于gccg++区别的问题,并帮助他们确定在C语言开发中应该使用哪个工具。首先,我要回顾一下自己了解的知识点,确保准确性。 我记得gcc是GNU Compiler Collection的缩写,支持多种编程语言,包括C、C++、Objective-C等。而g++则是专门用于编译C++代码的编译器。不过,用户可能容易混淆两者在处理CC++时的具体行为差异。 接下来,我需要查阅相关的资料或者已有的知识,确认以下几点: 1. 当使用gcc编译C代码时,是否默认链接C标准库,而不会自动链接C++标准库? 2. 如果用户错误地使用g++来编译C语言程序,会有什么影响?比如是否可能导致一些语法上的不兼容,或者引入不必要的C++特性? 3. 在编译链接阶段,gccg++在默认选项上的差异,比如是否自动链接数学库(-lm)或者其他库? 另外,用户提供的引用内容中,引用[1]提到了条件编译宏__cplusplus,这可能与g++在处理CC++代码时的预处理相关。当使用g++编译时,会定义这个宏,而用gcc编译C代码时则不会。这一点可能需要提及,特别是在混合使用CC++代码的情况下如何正确处理头文件。 引用[3]提到了栈内存堆内存的分配,以及迭代器的使用,但这可能与当前问题关联不大,不过如果涉及到编译器的内存管理差异,可能需要考虑。但暂时看来,用户的问题主要集中在工具选择上,而不是具体的内存管理。 引用[4]讨论了C++中的左值右值,以及移动语义,这可能与g++的C++11或更高版本的支持有关,但用户的问题是针对C语言开发,所以这部分可能不需要深入,除非涉及到编译器对C标准的支持情况。 现在,我需要组织回答的结构,确保清晰明了。首先解释gccg++的基本区别,然后详细说明它们在处理CC++代码时的不同行为,特别是编译链接阶段的差异。接着给出明确的建议,在C语言开发中使用哪个工具更合适,并可能提到一些注意事项,比如如何正确链接库或者处理头文件。 需要特别注意用户提到的引用[1]中的内容,当需要同时兼容CC++时,使用条件编译__cplusplus宏,这时候如果用g++编译C代码,可能会启用这些条件编译部分,而gcc则不会。这可能影响头文件的处理,但如果是纯C项目,使用gcc会更合适,避免不必要的宏展开。 还要考虑用户可能的误区,比如认为gcc只能编译C,而g++只能编译C++,但实际上两者都可以处理多种语言,只是默认行为不同。需要澄清这一点,避免用户混淆。 最后,生成相关问题,帮助用户深入理解,比如如何强制gcc使用C++标准,或者如何确保C代码在g++下的兼容性等问题。</think>### GCCG++的核心区别及C语言开发工具选择 #### 一、基础定位差异 1. **GCC**(GNU Compiler Collection) - 多语言编译器集合,原生支持C、C++、Fortran等 - 编译C代码时默认调用`cc1`前端,不自动链接C++标准库 - 编译命令示例: ```bash gcc -std=c11 main.c -lm # 显式链接数学库 ``` 2. **G++** - 专为C++设计的编译器前端,强制以C++方式处理源代码 - 默认启用C++语法检查,即使输入`.c`文件也会按C++编译 - 自动链接`libstdc++`(C++标准库) #### 二、关键行为对比表 | 特征 | GCC编译C代码 | G++编译C代码 | |---------------------|----------------------|----------------------| | 预处理宏`__cplusplus` | 未定义 | 已定义[^1] | | 函数重载 | 禁止 | 允许 | | `void*`自动转换 | 需要显式转换 | 隐式转换 | | 标准库链接 | 仅`libc` | `libc`+`libstdc++` | #### 三、C语言开发推荐方案 1. **纯C项目必选GCC** - 避免C++语法污染(如`//`注释在C89不兼容) - 示例安全编译命令: ```bash gcc -pedantic-errors -Wall -Wextra -std=c17 src/*.c ``` 2. **混合编程场景** - 使用`extern "C"`包装C函数声明: ```c #ifdef __cplusplus extern "C" { #endif void c_function(int); #ifdef __cplusplus } #endif ``` #### 四、常见误区解析 - **误区**:GCC不能编译C++ **事实**:`gcc main.cpp -lstdc++`可编译C++,但需手动链接库 - **误区**:G++编译的C代码更高效 **事实**:两者后端代码生成器相同,性能无差异 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值