“gcc和g++的区别”以及“gcc工作流程”问题请教
时间:2009-05-16
来源:互联网
误区一: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,二者等价。 |
这个是网上盛传的一份文档,有些地方很困惑,还请大侠来解惑~~
对于误区一:
gcc和g++是否只根据文件的后缀名来决定文件的是c还是c++?
对于gcc,只有.c才是c程序,其他的诸如C cpp cxx都是c++程序?
而对于g++,上面提到的都是c++?
对于误区三:
不管gcc还是g++,他们都是通过调用其他的程序来完成编译、连接工作的。特别的是这里提到的链接,这个不是ld的工作么?怎么说是g++或者gcc -lstdc++来完成的呢?
还有g++在链接时会调用gcc,又是怎么回事呢?gcc和g++编译时都是通过调用cc1或者cc1plus来完成的,这里g++在编译阶段会自动调用gcc做何理解呢?
作者: lofeng 发布时间: 2009-05-16
写这种混淆视听文章的家伙该打屁屁!
扫盲:
GCC 早期意思是 GNU C Compiler,专指 GNU 的 C语言 编译器;
随着其发展加入常见计算机语言支持,意思变为现在的 GNU Compiler Collection。
如果您自己不是太明白,那请按习惯做:gcc 编译 c 程序,g++ 编译 c++ 程序。
如果想利用一下 c++ 强大的检查能力,那可以使用 g++ 来编译 c 程序。
这样做,骨子里是“把 c++ 当作 更好的 c 来看待”,属于恶习。
正确的做法是,养成良好的编程习惯,而不应依赖编译器来查错。
用 gcc 直接编译 c++ 同样属于恶习。
您可以把“连接”看成编译过程的一部分,也可以把编译过程看作若干个独立步骤,视您具体目的而定。
一般的编译过程不需要您考虑这些。
作者: 聚焦深空 发布时间: 2009-05-16
这个网上很多的,只是不知道是谁第一个写出来的
深空老大,您说的很有道理,但是有些地方,我很想知道为什么是那样的,所以就会有些很奇怪的问题
gcc编译c++时需要加上-lstdc++选项
g++编译c源码时,是把它作为c程序来处理还是c++程序来处理的呢?链接时是使用libstdc还是libstdc++呢?
在GCC:The Complete Reference中看到:
A version of gcc that sets the default language to C++ and automatically includes the standard C++ libraries when linking. This is the same as g++. |
在code::block中的设置中有看到:
Linker for dynamic libs:g++.exe
linker for static libs:ar
这个又是什么意思呢?linker的工作不是都是由ld来完成的么?怎么会涉及到g++和ar呢?
作者: lofeng 发布时间: 2009-05-16
您可以把“连接”看成编译过程的一部分,也可以把编译过程看作若干个独立步骤,视您具体目的而定。 |
我一直都是把链接看做编译过程的一部分,因为我觉得编译的最终结果是得到可执行的二进制文件,所以肯定包含linker这一步工作
作者: lofeng 发布时间: 2009-05-16
如果真的感兴趣、或者精力过剩,那您可以找本 编译原理 方面的书补补,这些东西解释清楚本就是一本书。
如果这样还是不能满足,那您可以打开 gcc 的源代码好好读读(不妨从代码量小的早期 gcc 版本开始)、或建立一个简单的计算机语言程序(不妨从写计算器开始)。
您需要明白的是,习惯上什么是正确的,习惯上什么是错误的,而不是您认为什么怎么样。
下面是您需要知道的:
/usr/bin/cpp 是 gnu 的 c语言 预处理器,
/usr/bin/gcc 是 gnu 的 c语言 编译器,
/usr/bin/g++ 是 gnu 的 c++语言 编译器,/usr/lib/libstdc++.* 是 gnu 的 c++语言 支持的一部分,
c++语言 是 c语言 的 超集,c++语言 完全兼容 c语言,(如果不满意这个解释,您可以找找 c++、c 标准看看)
/usr/bin/as 是 gnu 的 汇编器,
/usr/bin/ld 是 gnu 的 链接器,
我们习惯上说的 编译(习惯用法) 实际是由 预处理、编译(这个才是其本意)、汇编、链接 这些步骤组成,默认 gcc g++ 会自动为您完成整个 编译链接 过程。
作者: 聚焦深空 发布时间: 2009-05-16
譬如这些:
gcc并不能说是gnu的c编译器,他只是个front-end,具体的编译工作是cc1来完成的
gcc并不是直接调用ld的,是通过collect2来的,但是这个过程又是怎样的?collect2是通过什么方法来找到合适的ld的?
作者: lofeng 发布时间: 2009-05-17
GCC uses a utility called collect2 on nearly all systems to arrange to call various initialization functions at start time. The program collect2 works by linking the program once and looking through the linker output file for symbols with particular names indicating they are constructor functions. If it finds any, it creates a new temporary `.c' file containing a table of them, compiles it, and links the program a second time including that file. |
作者: lofeng 发布时间: 2009-05-17
The actual calls to the constructors are carried out by a subroutine called __main, which is called (automatically) at the beginning of the body of main (provided main was compiled with GNU CC). Calling __main is necessary, even when compiling C code, to allow linking C and C++ object code together. (If you use -nostdlib, you get an unresolved reference to __main, since it's defined in the standard GCC library. Include -lgcc at the end of your compiler command line to resolve this reference.) |
作者: lofeng 发布时间: 2009-05-17
The program collect2 is installed as ld in the directory where the passes of the compiler are installed. When collect2 needs to find the real ld, it tries the following file names: * a hard coded linker file name, if GCC was configured with the --with-ld option. * real-ld in the directories listed in the compiler's search directories. * real-ld in the directories listed in the environment variable PATH. * The file specified in the REAL_LD_FILE_NAME configuration macro, if specified. * ld in the compiler's search directories, except that collect2 will not execute itself recursively. * ld in PATH. |
第三个选项跟第六个选项有什么分别得呢?
作者: lofeng 发布时间: 2009-05-17
您现在不停发的贴讨论的问题范围已经明显超出标题范围。
整个论坛上对这些问题清清楚楚的人估计不超过 10 个,偶大概能算半个的半个,您已经比偶强多了。
所以解决您现在疑问的最好办法,还是读 gcc 源码,把 gcc binutils 官网文档过一遍先 是个不错的主意。
作为习惯的一部分,请注意 libexec 对应目录下的程序 一般 不是给用户直接使用的,而是由其他程序调用简洁执行,比如您提到的 cc1 等 是由 gcc 调用执行。
/usr/bin/gcc 本身确实是前端,但不应按您想当然的方式理解。
如果愿意,您可以把其当作模块化编程的一个范例。
要知道 gcc 现在几乎无处不在,并且正在被移植到 更多的OS、更多的硬件平台。
您真正应该考虑的 是 为什么存在这些习惯(传统)?为什么要这样做?
另,请 给出 引用 出处,断章取义会害死人的。
作者: 聚焦深空 发布时间: 2009-05-17
http://gcc.gnu.org/onlinedocs/gccint....html#Collect2
下面是gcc driver 控制架构,这幅图摘自台湾的一个gcc研究小组的报告:
gcc并不能说是gnu的c编译器,他只是个front-end,具体的编译工作是cc1来完成的 gcc并不是直接调用ld的,是通过collect2来的,但是这个过程又是怎样的?collect2是通过什么方法来找到合适的ld的? |
只是上面那幅图没有涉及到collect2,而gcc -v test.c中的信息表明直接调用的是collect2而不是ld,这样collect2跟ld之间是怎样交互的就有点困惑。正如在第七贴中提到的,是否是那样的一个过程?
QQ截图未命名10.png (15.6 KB, 47 次查看) |
作者: lofeng 发布时间: 2009-05-17
看到标题进来的,发现自己是 白脖。
这水真深阿.
作者: linux_pro 发布时间: 2009-05-17
作者: linux_pro
标题和内容不符合....
看到标题进来的,发现自己是 白脖。 这水真深阿. |
作者: lofeng 发布时间: 2009-05-17
没关系,大伙都是白脖。
楼主的问题 是 大杀器。
@lofeng
您给出的图 和 偶上一帖给出的流程 是 等效的,只是更清楚一些。
对大多数人 /usr/bin/gcc 就是编译器,对 gcc 开发者 或 编译原理研究者 才有必要分析到您感兴趣的层次。
如果您准备移植 gcc 到一个 新OS,参照 gcc 官网的移植指南一定会非常开心。
您会发现 gcc 源代码的结构非常适于移植,这才是 分出 前后端 的 真正意义。
精神上,偶支持您把这些问题弄清楚。
但偶会不停的给您泼冷水,就像前面说的那是 gcc 开发者 或 编译原理研究者 才需要关心的。
作者: 聚焦深空 发布时间: 2009-05-17
http://www.cppblog.com/romangol/arch.../19/47595.html gcc: CreateProcess: No such file or Directory 错误 这个问题在google里面很多人发问,但是没有一个完整的解答,下面给出一个完整的解答 产生这个错误有两个原因: 第一是gcc无法找到安装目录里面的libexec目录里面的工具,通常这些工具包括cc1.exe,cc1plus.exe,collect2.exe,它们通常存放在: 安装目录\libexec\gcc\mingw32\4.3.0 第二是gcc无法找到mingw目录里面binutils的工具,它们通常存放在 安装目录\mingw32\bin 这两个目录的名字并不完全固定,根据不同组织编译的gcc各有不同,比如mingw官方编译的gcc4.3.0 alpha,上述目录就是 安装目录\gcc\i386-pc-mingw32\4.3.0 而官方提供的binutils包里面是 安装目录\i686-pc-mingw32\bin 只要这两个地方没有设置好,就可能导致CreateProcess错误,那么,有没有什么好办法能够确定这里应该怎样命名呢?办法是用16进制编辑器打开gcc.exe,搜索GCC_EXEC_PREFIX,当搜索到该字符串(不止一个)时,观察后面是否出现版本号4.3.0,如果出现,后面紧接着的就是路径,如果是mingw32那么上面的命名就应该是 安装目录\libexec\gcc\mingw32\4.3.0 安装目录\mingw32\bin 如果是其他的例如i686-pc-mingw32,那么名称相应的变为 安装目录\libexec\gcc\i686-pc-mingw32\4.3.0 安装目录\i686-pc-mingw32\bin |
作者: lofeng 发布时间: 2009-05-17
楼主的问题 是 大杀器。 |
俺只是想多了解一点 这样碰到一些奇怪的问题时就会明白问题出在哪里
作者: lofeng 发布时间: 2009-05-17
作者: lofeng
很困惑这里为什么会出现这个错误,难道gcc编译的时候是将调用的程序诸如cc1等的路径hard coded的?
|
再重复一遍,对于一般用户 /usr/bin/gcc /usr/bin/g++ (gcj g77 ……)就是人机接口,gcc 内部的东西当作 黑盒 看即可。
看过您所有帖子,但一直没明白您在做什么。
如果因为工作关系需要在 windows 下编译程序,直接安装适当版本的编译器和支持程序 干活就是,根本不需要自己手工编译工具链的,各种版本的都有现成的。
如果是研究目的,选 windows 已犯大忌,使用 MingGW 更是大忌(不足以 bootstrap 工具链),最不济也应使用 Cygwin(只是运行稍慢些,但完整),最好还是老老实实选合适的系统环境,请不要继续浪费自己的时间。
作者: 聚焦深空 发布时间: 2009-05-17
作者: linux_pro 发布时间: 2009-05-18
我是干嘛的不重要,在接触一些新东西时,总是允许有点想法的吧。呵呵~~
有很多地方,我想搞得清楚一点,譬如说做LFS时,如果只是按照手册一步步来,而不明白为什么要那样做,又有多大的意义和价值呢?
作者: lofeng 发布时间: 2009-05-18
lz 干嘛的,咱们不用关心。
不过把 MinGW 用到实际工作中的,真的很少见。
@lofeng
很遗憾,偶说的 您一点也听不进去,看来还是温度不够。
建议您冷处理一下,等几天或个把月再回来看看您自己的问题,您会有收获的。
不要再跑题了。
LFS/CLFS 并不是解决您的这些问题的,手册仅仅是参考罢了。
如果得到丁点 LFS/CLFS 真传,您会明白重点是,找到问题,接着自己动手解决问题。
您的问题更底层一些,大部分已经超出 LFS/CLFS 范围,合理的解决问题的方法已经给您重复多遍:阅读 gcc 源代码。
等您把自己的问题弄清楚,欢迎您把自己的收获用普通人能明白的方式反馈回来。
不要再浪费时间。
祝好运!
作者: 聚焦深空 发布时间: 2009-05-18
现在这类工具用的人很多的
我现在就经常用winavr
至于LFS/CLFS手册,我也知道它给出的只是个参照,但是手册中的很多命令都不是很明白,那这样做下去又有什么意思呢?而且很多人都是参照别人给出的成功编译过程来编译的,参照那些命令来的,这样也算是解决了问题么?
您说我的问题太底层了,在这里基本上是不能得到满意的答案。而您给出的解决之道,对于个人来说工作量太大,上百万行的代码,利用业余时间基本上是完成不了这类任务的。台湾的那个gcc研究小组四个人,用了一年的时间,也没有完全研究透gcc core。
作者: lofeng 发布时间: 2009-05-18
您带着问题读,需要读所有源代码?
针对您特定硬件平台、特定操作系统、特定编译器,需要阅读的范围就更小了。
打个不恰当的比方:
您吃东西前,会不会去分析营养成分、来源、制作流程、价格、甚至核酸序列?
您的目的决定您的适度行为。
如果您过度行为,您说这是什么症状。
问题应该在适度的层次、在适合自己理解能力的范围解决。
LFS/CLFS 原本就不是给初级用户准备的,手册上前几章写的很清楚。
遗憾的是,大多数人是以“学习”的态度来进行 LFS/CLFS,甚至连手册也不细读,这是本末倒置。
毁灭版主一向劝人多读手册。
偶更进一步劝人回头是岸,先积累经验再回来。
请先冷静下来。
作者: 聚焦深空 发布时间: 2009-05-19
--毁灭版主一向劝人多读手册。
--偶更进一步劝人回头是岸,先积累经验再回来。
我是手册都没读,直接抱这坚果的书上的,死的惨后才想起来linuxsir有lfs.....然后看到各位大牛了..哈哈
to lofeng
--至于LFS/CLFS手册,我也知道它给出的只是个参照,但是手册中的很多命令都不是很明白,那这样做下去又有什么意思呢?而且很多人都是参照别人给出的成功编译过程来编译的,参照那些命令来的,这样也算是解决了问题么?
要是知道每条命令,恐怕就是设计者了.而不是用户了。
作者: linux_pro 发布时间: 2009-05-19
作者: fender010 发布时间: 2009-05-21
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28