我们在编译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的

g++ gcc 的区别的更多相关文章

  1. 详解C/C++ 编译 g++ gcc 的区别

    我们在编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而c++代码用g++, 或者说编译用gcc,链 接用g++,一时也不知哪个说法正确,如果再遇上个ex ...

  2. ACM提交,C++,G++,C,GCC的区别

    今天做了一道水题,POJ-1004,水题一个,12个double类型的数求平均数 但是, #include <iostream> #include <cstdio> using ...

  3. g++ gcc

    编写一个main.cpp,linux 下执行步骤: (1)g++ mian.cpp ./a.out 后缀名是.cpp,编译完成后的可执行文件一般是a.out,也可以自己指定. (2) 编译命令(C): ...

  4. oj 中G++和C++区别(转)

    1.输出double类型时,如果采用G++提交,scanf采用%lf,prinf采用%f,否则会报错 2.使用GCC/G++的提醒: 对于64位整数, long long int 和 __int64 ...

  5. 英语发音规则---/ŋ/与/ŋg/的读音区别

    英语发音规则---/ŋ/与/ŋg/的读音区别 一.总结 一句话总结: 1.位于词中间的字母组合ng,有时读作/ ŋ /,有时读作/ ŋg/? singer ['sɪŋə] n. 歌手 ringing ...

  6. vim g s 替换区别

    vim g s 替换区别     PS:一篇好文收藏备用,今天用它解决了一个大问题. 发信人: vale (浅谷), 信区: VIM标  题: global命令详解 发信站: 水木社区 (Fri Ju ...

  7. GCC/gcc/g++/CC/cc区别

    平常在Linux上经常会用到gcc或者g++来编译程序,但对这两者的理解也就停留在一个是用来编译C程序,另一个是用来编译C++程序的(请注意:这种说法是有问题的,待会改进). 1. GCC GCC,是 ...

  8. [转]G++与GCC的区别

    转自http://www.52pojie.cn/thread-58109-1-1.html 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当 ...

  9. Linux中gcc与g++编译器的区别

    一.对于C文件 对于C文件gcc和g++所做的事情确实是一样的,g++在编译C文件时调用了gcc. 二.对于C++文件 1.预处理 预处理gcc与g++做了相同的事. 2.编译 gcc无法自动和c++ ...

随机推荐

  1. UWP app HelloWorld 的创建

    步骤 1:在 Visual Studio 中创建新项目 启动 Visual Studio 2015 RC.将出现 Visual Studio 2015 RC 起始页. (从现在开始,我们将 Visua ...

  2. JS正则表达式验证账号、手机号、电话、邮箱、货币

    验证帐号是否合法验证规则:字母.数字.下划线组成,字母开头,4-16位. function checkUser(str){ var re = /^[a-zA-z]\w{3,15}$/; if(re.t ...

  3. HTML总结1

    1.html基本结构 <html>  <head>   <title>我的第一个网页</title>  </head>  <body ...

  4. 动态的显示当前的时间---setInterval的用法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Struts2 删除后直接直接到List显示页面

    package com.sun; import java.util.List; import java.util.Map; import org.hibernate.Session; import o ...

  6. Java反射和动态代理

    Java反射 反射机制 RTTI 编译器在编译时打开和检查*.class文件 反射机制 运行时打开和检查*.class文件 Java反射常见的方法 java反射的应用 setAccessible(bo ...

  7. Visual Studio 2013 无法启动 IIS Express 的解决办法

    关于 ASP.NET Web 开发服务器.本地 IIS和 IIS Express 的区别,请参见<VS2013无法启动IIS Express Web的解决办法>,此文章最后提到的部分,即是 ...

  8. SQL批量信息保存(XML格式字符串数据)

    /* *功能:SQL批量信息录入 *此存储过程获取表单信息,插入表中.*/CREATE  PROC [dbo].[sp_SaveToMX1]@XML text   --明细表XML字符串信息ASBEG ...

  9. Oracle 创建分页存储过程(转帖)

    原贴地址:http://19880614.blog.51cto.com/4202939/1316560 ps:源代码还有很多错误,我修改了 ------------------------------ ...

  10. 重新开始学习javase_控制程序流程

    @学习thinking in java 二.控制程序流程 负数使用 Java 运算符:运算符以一个或多个自变量为基础,可生成一个新值.自变量采用与原始方法调用不同的一种形式,但效果是相同的.根据以前写 ...