[原创]GCC系列教程 一

新手涉及到的教学或入门贴,推荐新手必看,版主维护
墨尘
帖子: 129
注册时间: 2007-11-22 17:25
送出感谢: 0
接收感谢: 2 次
联系:

[原创]GCC系列教程 一

#1

帖子 墨尘 » 2008-09-11 16:23



这几天突然想学习下gcc,就在网上搜集些资料,总结下制作个系列教程,更好的帮助自己学习,希望也能给大家一点帮助,就这样啦。
欢迎大家到偶的Blog给点支持啦:http://hi.baidu.com/god_86
不经意间,GCC已发展到了4.3的版本,尽管在软件开发社区之外乏人闻问,但因为GCC在几乎所有开源软件和自由软件中都会用到,因此它的编译性能的涨落会直接影响到Linux 、Firefox 乃至于OpenOffice.org和Apache等几千个项目的开发。因此,把GCC摆在开源软件的核心地位是一点也不为过。另一方面,GCC4.3的出现,正在牵引着广大程序员们的心。如果我们非要用一个词来说明GCC与程序员之间的关系,那无疑是"心随心动"。
历史篇
作为自由软件的旗舰项目,Richard Stallman 在十多年前刚开始写作 GCC 的时候,还只是把它当作仅仅一个 C 程序语言的编译器;GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年 的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。而 GCC 也不再单只是 GNU C 语言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。另一方面,说到 GCC 对于各种硬件平台的支持,概括起来就是一句话:无所不在。几乎所有有点实际用途的硬件平台,甚至包括有些不那么有实际用途的硬件平台。
Gcc 简介
Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。Gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
官方网站:http://gcc.gnu.org/

gcc是linux的唯一编译器,没有gcc就没有linux,gcc的重要性就不可言喻啦。居然这么重要,那就很值得我们来好好研究下啦。好啦,开始我们的gcc之旅吧!


首先消除gcc和g++误区吧。
gcc和g++都是GNU(组织)的一个编译器。

误区一: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的。

后面还会继续啦 (*^__^*) 嘻嘻……
头像
zhuqin_83
帖子: 10606
注册时间: 2006-05-13 4:02
送出感谢: 0
接收感谢: 7 次
联系:

#2

帖子 zhuqin_83 » 2008-09-11 21:29

gcc不是linux的唯一编译器。只不过不像其他编译器那样有限制,版权之类的困扰。性能上虽说不算差,但在一些方面比不过icc。
HP Pavilion DV6-2064CA: AMD Turion II Ultra Dual-Core Mobile M640, HD4650, 2GBx2 DDR2-800, Seagate 500GB 7200RPM SATA, BD-ROM
DELL UltraSharp 2209WA
Arch64, Testing repo
poet
帖子: 2841
注册时间: 2006-09-11 22:47
送出感谢: 0
接收感谢: 4 次

#3

帖子 poet » 2008-09-11 22:11

extern C 仅仅当需要混用C代码和C++代码时才需要使用。

如果你使用g++编译你的所有C代码,那么就不需要externC

仅仅当你需要将使用gcc编译的C代码目标文件和任意方法编译出的C++代码的目标文件时,才需要使用extern C。

也就是说,仅仅当你需要在C++中连接一份你拿不到源代码的C目标文件或者C库时,才需要使用extern C。
头像
cigerma
帖子: 90
注册时间: 2008-06-13 12:00
送出感谢: 0
接收感谢: 0

#4

帖子 cigerma » 2008-09-11 23:18

楼主坚持写啊,我也来学习学习!
头像
waiqcn
帖子: 5
注册时间: 2008-09-13 11:37
送出感谢: 0
接收感谢: 0
联系:

#5

帖子 waiqcn » 2008-09-13 12:28

谢谢楼主的资料呵呵
头像
casual0402
帖子: 116
注册时间: 2008-04-05 14:18
来自: Fujian,China
送出感谢: 0
接收感谢: 0
联系:

#6

帖子 casual0402 » 2008-09-18 8:21

呵呵 同样在学习中
头像
bones7456
论坛版主
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
送出感谢: 0
接收感谢: 8 次
联系:

#7

帖子 bones7456 » 2008-09-18 9:38

分别对应前面红色标注的部分。
没看到红色,LZ再整整格式吧。
关注我的blog: ε==3
头像
gamespy
帖子: 126
注册时间: 2007-02-22 18:20
送出感谢: 0
接收感谢: 0
联系:

Re: [原创]GCC系列教程 一

#8

帖子 gamespy » 2008-10-03 18:35

为什么用GCC编译同一份源代码出来的程序比VS的大很多?
wanzihrg
帖子: 223
注册时间: 2008-03-15 10:34
送出感谢: 0
接收感谢: 0

Re: [原创]GCC系列教程 一

#9

帖子 wanzihrg » 2008-10-05 1:10

支持楼主接着写!
头像
guiwen1158
帖子: 1078
注册时间: 2008-05-11 11:10
来自: 深圳
送出感谢: 0
接收感谢: 0
联系:

Re: [原创]GCC系列教程 一

#10

帖子 guiwen1158 » 2008-10-09 21:07

好好学习,谢谢LZ。
lshguang89
帖子: 61
注册时间: 2007-07-11 18:51
来自: SYSU
送出感谢: 0
接收感谢: 0
联系:

Re: [原创]GCC系列教程 一

#11

帖子 lshguang89 » 2008-10-27 10:29

学习............ :em02 :em11
xininye
帖子: 44
注册时间: 2008-01-18 23:24
送出感谢: 0
接收感谢: 0

Re: [原创]GCC系列教程 一

#12

帖子 xininye » 2009-01-27 23:40

学习!!支持LZ写
头像
topbluecat
帖子: 411
注册时间: 2008-03-27 21:56
送出感谢: 0
接收感谢: 0
联系:

Re: [原创]GCC系列教程 一

#13

帖子 topbluecat » 2009-02-02 20:36

为什么用GCC编译同一份源代码出来的程序比VS的大很多?
可以用优化参数 -O2或者-O3来优化。
vp110
帖子: 5
注册时间: 2009-11-13 21:06
送出感谢: 0
接收感谢: 0

Re: [原创]GCC系列教程 一

#14

帖子 vp110 » 2009-11-13 21:41

:em09
学习了
头像
chenzw
帖子: 76
注册时间: 2008-11-03 14:59
送出感谢: 0
接收感谢: 0
联系:

Re: [原创]GCC系列教程 一

#15

帖子 chenzw » 2010-03-15 17:43

嗯,支持一下哈
要好好混论坛

blog: http://zhiwei.in
回复

回到 “教学和常见问答”