gcc和g++使用澄清

一:gcc与g++比较

编译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++命名有什么不同
[[email protected] G++]# g++ -S me.cpp
[[email protected] G++]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   CppPrintf, @function
[[email protected] GCC]# gcc -S me.cpp
[[email protected] GCC]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   CppPrintf, @function
完全相同!
               
2. 去掉me.h中extern "C",看用gcc和g++命名有什么不同
[[email protected] GCC]# gcc -S me.cpp
[[email protected] GCC]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   _Z9CppPrintfv, @function
[[email protected] G++]# g++ -S me.cpp
[[email protected] G++]# less me.s
.globl _Z9CppPrintfv        //注意此函数的命名
        .type   _Z9CppPrintfv, @function
完全相同!
【结论】完全相同,可见extern "C"与采用gcc/g++并无关系,以上的试验还间接的印证了前面的说法:在编译阶段,g++是调用gcc的。

二:gcc和g++的包含头文件库文件方法

-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。

好了现在我们知道怎么得到库名,当我们自已要用到一个第三方提供的库名字libtest.so,那么我们只要把 libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里 的函数,我们还需要与libtest.so配套的头文件)

放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放 在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr /X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L /aaa/bbb/ccc -ltest

另外,大部分libxxxx.so只是一个链接,以RH9为例,比如libm.so它链接到/lib/libm.so.x,/lib/libm.so.6又链接到/lib/libm-2.3.2.so,

如果没有这样的链接,还是会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一个链接就可以了ln -s libxxxx-x.x.x.so libxxxx.so

手工来写链接参数总是很麻烦的,还好很多库开发包提供了生成链接参数的程序,名字一般叫xxxx-config,一般放在/usr/bin目录下,比如

gtk1.2的链接参数生成程序是gtk-config,执行gtk-config --libs就能得到以下输出"-L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic

-lgmodule -lglib -ldl -lXi -lXext -lX11 -lm",这就是编译一个gtk1.2程序所需的gtk链接参数,xxx-config除了--libs参数外还有一个参数是--cflags用来生成头 文件包含目录的,也就是-I参数,在下面我们将会讲到。你可以试试执行gtk-config --libs --cflags,看看输出结果

现在的问题就是怎样用这些输出结果了,最笨的方法就是复制粘贴或者照抄,聪明的办法是在编译命令行里加入这个 `xxxx-config --libs --cflags`,比如编译一个gtk程序:gcc gtktest.c `gtk-config --libs --cflags`这样就差不多了。注意`不是单引号,而是1键左边那个键。

5、-include和-I参数

-include用来包含头文件,但一般情况下包含头文件都在源码里用#include xxxxxx实现,-include参数很少用。-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但 是如果头文件不在/usr/include里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I /myinclude参数了,如果不加你会得到一个"xxxx.h: No such file or directory"的错误。-I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。
 
结论例子:

g++ curltest.cpp -o curltest -L/mnt/hgfs/windows/curl-7.19.5/lib/.libs -lcurl -I/mnt/hgfs/windows/curl-7.19.5/include

时间: 2024-08-28 06:33:22

gcc和g++使用澄清的相关文章

gcc 与 g++的区别

原文: http://www.cnblogs.com/wb118115/p/5969775.html ------------------------------------------------------------------------------------ 看的Linux公社的一篇文章,觉得不错,内容复制过来了. 其实在这之前,我一直以为gcc和g++是一个东西,只是有两个不同的名字而已,今天在linux下编译一个c代码时出现了错误才找了一下gcc和g++的区别. 先描述一下今天遇

Linux下安装gcc 、g++ 、gfortran编译器

一.ubuntu下gcc/g++/gfortran的安装 1.安装 (1).gcc ubuntu下自带gcc编译器.可以通过“gcc -v”命令来查看是否安装. (2).g++ 安装g++编译器,可以通过命令“sudo apt-get install build-essential”实现. 执行完后,就完成了gcc,g++,make的安装.build-essential是一整套工具,gcc,libc等等. 通过“g++ -v”可以查看g++是否安装成功. 注:“sudo apt-get inst

【Linus】配置gcc、g++和gdb

从 Linux中使用gcc来编译C程序,使用g++来编译C++程序,使用GDB来调试程序,这些使用工具都需要自己进行安装,那么应该怎样配置这些工具呢? 1.查看vim信息,并查看是否存在.vimrc和.viminfo这样的配置文件 2.配置gcc.g++ Centos中使用yum来配置gcc和g++. 若要安装gcc,则在命令行中输入:yum -y install gcc,按回车键就能够进行gcc的安装:若要安装g++,则需要在命令行中输入:yum -y install gcc++,就能够进行g

怎样在Centos中配置gcc、g++、和gdb?

linux中使用gcc来编译C程序,使用g++来编译C++程序,使用GDB来调试程序,这些使用工具都需要自己进行安装,那么应该怎样配置这些工具呢? 首先,在命令行中输入vi查看一下vim的信息如下: 然后,输入ls -a查看是否存在.vimrc和.viminfo这样的配置文件,结果如下: 1.配置gcc.g++ Centos中使用yum来配置gcc和g++,若要安装gcc,则在命令行中输入:yum -y install gcc,按回车键就能够进行gcc的安装,若要安装g++,则需要在命令行中输入

gcc与g++的一些关系

Gcc 简介Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大.性能优越的多平台编译器,是GNU的代表作品之一.Gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%. gcc是linux的唯一编译器,没有gcc就没有linux,gcc的重要性就不可言喻啦. 一:gcc与g++比较 编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而 c++代码用g++,或者说编译用

GCC与G++那些事儿

StackOverflow上一个很有名的问题,gcc和g++到底有什么区别? 答案如下: GCC: GNU Compiler Collection 指的是GNU编译器所支持的所有不同的类型的语言 gcc: GNU C  Compiler g++:GNU C++ Compiler 主要的区别在于: 1.gcc会将.c文件和.cpp文件分别当做C和C++来编译. 2.g++会将.c文件和.cpp文件都当做c++文件来编译. 3.如果使用g++链接目标文件,它会自动链接std C++ lib.然而gc

Linux下C/C++程序调试基础(GCC,G++,GDB,CGDB,DDD)

在写程序的时候,经常会遇到一些问题,比如某些变量计算结果不是我们预期的那样,这时我们需要对程序进行调试.本文主要介绍调试C/C++在Linux操作系统下主要的调试工具. 在Linux下写程序,C/C++主要的编译器有GCC/G++,ICC等,像我等穷码农,最喜欢GCC了,很大原因是他免费!所以,我们以GCC/G++为例介绍主要的调试工具. 分以下几个内容介绍: 1.调试之前的工作 2.选择调试工具 3.调试步骤 点我,请帮我投一票! 调试之前的工作 编译器在编译阶段需要产生可供调试的代码,才能被

gcc和g++的区别【转自中国源码网】

gcc和g++都是GNU(组织)的一个编译器. 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为.cpp的,两者都会认为是c++程序,注意,虽然c++是c的超集,但是两者对语法的要求是有区别的.C++的语法规则更加严谨一些.2.编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接

windows下安装CentOS及离线安装gcc、g++、cmake、make等工具

一.安装CentOS 参考雁过留痕Neo的博客之<Win7下安装CentOS 6.5双系统> http://blog.sina.com.cn/s/blog_86e874d30101e3d8.html 这篇写的很用心,但部分细节较为关键的未提及. 几点意见: 存放CentOS的镜像文件存放在新建的分区根目录,建议主分区,逻辑分区的话在安装过程中可能出现无法create linux分区.P.S分区大小5~10G,32位系统为FAT32格式,64位为ex4. 再新建一个分区,完成后删除分区.P.S大