gcc和g++的区别__C++中的extern C""

**********************************************************************

**********************************************************************

gcc和g++的区别

**********************************************************************

gcc/g++在执行编译工作的时候,总共需要4步 

  1.预处理,生成.i的文件[预处理器cpp] 

  2.将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs] 

  3.由汇编变为目标代码(机器代码)生成.o的文件[汇编器as] 

  4.连接目标代码,生成可执行程序[链接器ld]

 When you invoke GCC, it normally does preprocessing, compilation, assembly and linking.  The 

       "overall options" allow you to stop this process at an intermediate stage.  For example, the 

       -c option says not to run the linker.  Then the output consists of object files output by 

       the assembler. 

       -E  Stop after the preprocessing stage; do not run the compiler proper.  The output is in 

           the form of preprocessed source code, which is sent to the standard output. 

       -S  Stop after the stage of compilation proper; do not assemble.  The output is in the form 

           of an assembler code file for each non-assembler input file specified. 

**********************************************************************

********************************************************************** 

1、g++把.c 和.cpp都当成c++程序来编译了,而gcc将.cpp当c++程序来编译。 

编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接统统用g++了。 

示例: 

/********************************************************************** 

 * Compiler: gcc 4.5.1 20100924 (Red Hat 4.5.1-4) 

 * Last Update: Sun 27 May 2012 04:05:23 PM CST 

 * File Name: test.cpp 

 * Description: 

 ************************************************************************/ 

#include <iostream> 

int main() 

    std::cout<<"love"<<std::endl;    

    return 0; 

[test1@localhost tempCode]$ gcc -o test test.cpp 

/tmp/cczBzjdU.o: In function `main': 

test.cpp:(.text+0x14): undefined reference to `std::cout' 

collect2: ld returned 1 exit status 

[test1@localhost tempCode]$ g++ -o test test.cpp  用g++就能成功。

**********************************************************************

但如果要用gcc链接C++标准库的话,可以这样做

[test1@localhost tempCode]$ gcc -o test test.cpp -lstdc++ 

********************************************************************** 

2、__cplusplus这个宏标志着编译器将会把代码按C还是C++语法来解释。 

例如void foo(int x, int y); 

该函数被C编译器编译后在符号表中的名字为foo,而C++编译器则会产生像_Z3fooii之类的名字用来支持函数重载和类型安全连接。由于编译后在符号表中的名字不同,C++程序不能直接调用C函数。C++提供了一个C连接交换指定符号extern“C”来解决这个问题

**********************************************************************

**********************************************************************

**********************************************************************

C++中的extern C""

/**********************************************************************

* Compiler: gcc 4.5.1 20100924 (Red Hat 4.5.1-4)

* Last Update: Sun 27 May 2012 03:21:50 PM CST

* File Name: cExample.h

* Description: 

************************************************************************/

extern int funcTest(int a);

/**********************************************************************

* Compiler: gcc 4.5.1 20100924 (Red Hat 4.5.1-4)

* Last Update: Sun 27 May 2012 03:23:03 PM CST

* File Name: cExample.c

* Description: 

************************************************************************/

#include "cExample.h"

#include <stdio.h>

int funcTest(int x)

{

    printf("%d\n", x);

}

/**********************************************************************

* Compiler: gcc 4.5.1 20100924 (Red Hat 4.5.1-4)

* Last Update: Sun 27 May 2012 03:11:50 PM CST

* File Name: 1.cpp

* Description: 

************************************************************************/

//#include <stdio.h>

//#ifdef __cplusplus

//extern "C" 

//{

//#endif

#include "cExample.h"

//#ifdef __cplusplus

//}

//#endif

int main(int argc, char* argv[])

{

    funcTest(1);

    return 0;

}

下面用gcc的-S选项,只激活预处理和编译,把文件编译成为汇编代码。

[test1@localhost tempCode]$ gcc -S cExample.c 

[test1@localhost tempCode]$ gvim cExample..s 

.globl funcTest

.type funcTest, @function

funcTest:

查看汇编代码可以看到cExample.c 中的函数funcTest在符号表中的名字为 funcTest。

也可以用-c选项生成目标代码,直接查看目标代码在符号表中的名字。

 the   -c option says not to run the linker.  Then the output consists of object files output by  the assembler. 

[test1@localhost tempCode]$ gcc -c cExample.c      //生成目标文件

使用objdump - display information from object files. 

       -t  Print the symbol table entries of the file. 

[test1@localhost tempCode]$ objdump -t cExample.o

cExample.o:     file format elf32-i386 

SYMBOL TABLE: 

00000000 l    df *ABS* 00000000 cExample.c 

00000000 g     F .text 0000001c funcTest 

00000000         *UND* 00000000 printf 

[test1@localhost tempCode]$ g++ -o 1 1.cpp cExample.o 

/tmp/ccAodC5a.o: In function `main': 

1.cpp:(.text+0x11): undefined reference to `funcTest(int)' 

collect2: ld returned 1 exit status 

单独生成1.cpp的目标代码进行查看

[test1@localhost tempCode]$ g++ -c 1.cpp 

[test1@localhost tempCode]$ objdump -t 1.o 

1.o:     file format elf32-i386 

SYMBOL TABLE: 

00000000 l    df *ABS* 00000000 1.cpp 

00000000 g     F .text 0000001c main 

00000000         *UND* 00000000 _Z8funcTesti 

可看到funcTest在1.o符号表中的名字是_Z8funcTesti ,与funcTest在cExample.o符号表中的名字不同,故链接时失败了。

下面在1.cpp中加入extern “C”,这样子就告诉C++编译器将extern “C”{}所包括的东西按照C编译器去生成目标代码,这样子不会出现函数名在.cpp目标代码的符号表中的名字与.c目标代码中的名字不同。__cplusplus这个宏标志着编译器将会把代码按C还是C++语法来解释。

/**********************************************************************

* Compiler: gcc 4.5.1 20100924 (Red Hat 4.5.1-4)

* Last Update: Sun 27 May 2012 03:11:50 PM CST

* File Name: 1.cpp

* Description: 

************************************************************************/

#include <stdio.h>

#ifdef __cplusplus

extern "C" 

{

#endif

#include "cExample.h"

#ifdef __cplusplus

}

#endif

int main(int argc, char* argv[])

{

    funcTest(1);

    return 0;

}

[test1@localhost tempCode]$ g++ -c 1.cpp 

[test1@localhost tempCode]$ objdump -t 1.o 

1.o:     file format elf32-i386 

SYMBOL TABLE: 

00000000 g     F .text0000001c main 

00000000         *UND*00000000 funcTest 

再进行编译就能通过了。

[test1@localhost tempCode]$ g++ -o 1 1.cpp cExample.o 

[test1@localhost tempCode]$ ./1 

**********************************************************************

若直接用gcc  对1.cpp 和cExample.c 进行编译链接,会出错。正如上面所说gcc将1.cpp当作c++程序对待,将.c当c程序对待,故生成的符号表中的函数字称不同,链接时会出错。

[test1@localhost tempCode]$ gcc -o 1 1.cpp cExample.c 

/tmp/ccswh6XC.o: In function `main': 

1.cpp:(.text+0x11): undefined reference to `funcTest(int)' 

collect2: ld returned 1 exit status 

但用g++ 对1.cpp 和cExample.c 进行编译链接,就不会出错,因为无论是.c还是.cpp,g++都当成c++程序对待了。

[test1@localhost tempCode]$ g++ -o 1 1.cpp cExample.c 

**********************************************************************

**********************************************************************

 C++程序调用C标准库为什么不用加extern C””

由于C++程序要调用C标准库,所以考虑到这一点,在C头文件(.h头文件)中已经做了特殊的处理,即在编译C++程序的时候,对这些C头文件中声明的函数使用C调用机制(extern "C"),而不使用默认的C++调用机制,防止因C++函数调用机制出现在C库中找不到对应的函数的现象。

**********************************************************************

@@@@@@@@@@@@@@@@

参考:G++

基于GCC编译器先准备一些关于C和C++的知识:

gcc和g++的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值