gcc和g++的区别__C++中的extern C""
2017-07-27 10:18
405 查看
**********************************************************************
**********************************************************************
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
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++的区别
**********************************************************************
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
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++的区别
相关文章推荐
- gcc和g++的区别__C++中的extern C""
- 不同的编译器:GCC G++ C C++的区别
- GCC G++ C C++的区别
- GCC G++ C C++的区别(转载)
- 不同的编译器:GCC G++ C C++的区别
- 【转】不同的编译器:GCC G++ C C++的区别
- 分享:GCC G++ C C++的区别(转载)
- c调用c++、c++调用c 时所使用的extern "c" 的区别
- C/C++ gcc g++编译的区别
- 不同的编译器:GCC G++ C C++的区别
- c调用c++和c++调用c时所使用的extern "c"的区别
- GCC G++ C C++的区别
- 详解C/C++ 编译 g++ gcc 的区别
- GCC G++ C C++的区别
- C/C++ 中gcc和g++的对比与区别
- gcc编译c++的选项以及gcc与g++编译c++代码的区别
- Compiling "C" And "C++" Programs On Unix Systems - gcc/g++
- c和c++的区别&gcc和g++的区别
- 不同的编译器:GCC G++ C C++的区别
- GCC G++ C C++的区别