g++ -g -Wall -std=c++11 main.cpp

gcc -g -Wall -std=c11 main.cpp

如果不想每次写这个-std=C++11这个选项该怎么办呢?

  方法出处:http://stackoverflow.com/questions/16886591/how-do-i-enable-c11-in-gcc

  方法1:写Makefile

  方法2:取别名 :alias g++11="g++ -std=c++11"

--------------------------------------------------------------------------------------------------------------------------------

一般而言,在Linux下编译程序分为以下4个阶段:

  1. 预处理:编译处理宏定义等宏命令(eg:#define)——生成后缀为“.i”的文件   
  2. 编译:将预处理后的文件转换成汇编语言——生成后缀为“.s”的文件   
  3. 汇编:由汇编生成的文件翻译为二进制目标文件——生成后缀为“.o”的文件   
  4. 连接:多个目标文件(二进制)结合库函数等综合成的能直接独立执行的执行文件——生成后缀为“.out”的文件

在Linux下执行gcc与g++编译C++文件的差别:

  1. 后缀为.c的,gcc把它当作是C程序(cc/cpp才判定为C++源程序),而g++当作是c++程序
  2. gcc无法进行库文件的连接,即无法编译完成步骤4;而g++则能完整编译出可执行文件。(实质上,g++从步骤1-步骤3均是调用gcc完成,步骤4连接则由自己完成)

  gcc -E 执行到步骤1,只处理宏命令,需要用重定向生成文件

  gcc -S 执行到步骤2,生成文件.s

  gcc -c 执行到步骤3,生成文件.o

  g++ 分别编译于连接 .cc文件与.o文件

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

二: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

gcc g++ 支持c++11编译的标准和区别相关推荐

  1. 【转】gcc/g++ 链接库的编译与链接

    转自:gcc/g++ 链接库的编译与链接_Surge-CSDN博客_g++ 链接 gcc/g++ 链接库的编译与链接 surgewong@gmail.com Surge_surgewong_CSDN博 ...

  2. 【gcc/g++】1.编译器, 编译过程和基本参数

    "木叶飞舞之处" 一, gcc编译器 二, gcc的编译过程 1--完整版 1. 预处理 2. 编译 3. 汇编 4. 链接: 2--简化版 简化编译过程 3--编译完成 三, g ...

  3. gcc/g++ 链接库的编译与链接

          程序编译一般需要经预处理.编译.汇编和链接几个步骤.在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为"库"文件.在链接步骤中,连接器将从库文件取得所需的代码 ...

  4. g++使用C++11编译源文件

    g++ HelloWorld.cpp -std=c++11 转载于:https://blog.51cto.com/p6xos/1683858

  5. linux下安装或升级GCC 4.8以上版本(包括),以支持C++11

    本文转载自:http://www.cnblogs.com/lizhenghn/p/3550996.html C++11标准在2011年8月份获得一致通过,这是自1998年后C++语言第一次大修订,对C ...

  6. gcc/g++ 如何支持c11 / c++11标准编译

    gcc/g++ 如何支持c11 / c++11标准编译 linux中的编译环境默认可能不支持C++11语法,如R"(abc)"原始字符串. 那么如果一定要编译呢? 通过命令man ...

  7. RedHat gcc编译器版本升级到4.8.2支持C++11标准

    原来环境信息 Red Hat Enterprise Linux Server release 6.4 (Santiago) gcc4.4.7 升级到gcc4.8.2 gcc4.8以上版本才支持C++1 ...

  8. g++编译支持c++11的方法

    网上找了一下有两种方式: 方法一:直接在代码的cpp文件最开始的位置,添加如下代码: #pragma GCC diagnostic error "-std=c++11" 方法二:使 ...

  9. gcc 自动识别的文件扩展名,gcc/g++ -x 选项指定语言,不同 gcc 版本 -std 编译选项支持列表

    对于执行 C 或者 C++ 程序,需要借助 gcc(g++)指令来调用 GCC 编译器. 对于以 .c 为扩展名的文件,GCC 会自动将其视为 C 源代码文件 对于以 .cpp 为扩展名的文件,GCC ...

最新文章

  1. 13、Power Query-逆透视列的解析(上)
  2. Ubuntu中搭建Hadoop2.5.2完全分布式系统(一)
  3. 【转载保存】linux shell字符串切割成数组
  4. Windows 7 IIS HTTP 错误 403.14 - Forbidden
  5. 乐鑫esp8266基于freeRtos实现私有服务器本地远程OTA升级
  6. 2021-2025年中国丁酸衍生物行业市场供需与战略研究报告
  7. FirewallD常用命令及设置
  8. 做善良公社项目的经历和感受——善良公社
  9. 机器学习案例:预测自行车流量——基于Scikit-Learn
  10. vertica java_Vertica数据查询优化
  11. Python批量裁剪图形外围空白区域
  12. linux下查找某文件/文件夹所在的位置
  13. 2022最新软件测试面试题(含答案)
  14. java旧版下载地址_Java下载 - 最新版、历史版本的官方下载地址
  15. 苏州市区公积金与园区公积金新政策-乙类对比 包括住房公积金
  16. Unity3d 2019.3 通过 Ctrl 键让移动是固定步距
  17. mysql 备份数据库结账_简单的结账功能(可用于各种结账)
  18. ARM处理器体系结构总结
  19. Atitit r2017 r3 doc list on home ntpc.docx
  20. 高性能多层堆叠致动器 压电弯曲驱动器 压电执行器 压电控制器 压电放大器 压电管扫描器 压电致动器 压电陶瓷促动器 压电陶瓷管驱动器 压电陶瓷致动器 压电陶瓷驱动 压电陶瓷驱动器 是什么?

热门文章

  1. 13 不可能为条目xxxx GBB xxxx BSA xxxx确立账户
  2. ftp响应码以及解释说明是服务器返回,FTP命令字和响应码解释
  3. java如何实现计算数据的录入_Java如何实现键盘数据的录入?
  4. k8s初始化集群后kubectl get nodes错误
  5. 结构重参数化技术【为了模型压缩】:进可暴力提性能,退可无损做压缩
  6. public,protected,private
  7. vue动态监听窗口高度 - 全背景banner
  8. 纯css实现给图片加标签
  9. macos安装urar具体步骤_【2019】macOS重装系统出现“准备安装时出错“?
  10. mysql命令大全_Keeplived+mysql双master高可用如何实现?