大话C++:第2篇 C++编译器

1 C++常见编译器介绍

C++语言的编译器是将C++源代码转换为机器可执行代码的工具。以下是一些广泛使用的C++编译器:

  • GNU Compiler Collection (GCC):GCC是一个自由软件编译器集合,支持C、C++、Objective-C、Fortran、Ada和Go等多种编程语言。它是最流行的开源C++编译器之一,广泛用于各种操作系统和平台上。

  • Clang:Clang是基于LLVM的C、C++、Objective-C和Objective-C++编译器前端。它以其出色的错误消息、性能以及丰富的源代码静态分析工具而闻名。

  • Microsoft Visual C++ (MSVC):MSVC是微软开发的C++编译器,与Visual Studio集成。它为Windows平台提供了强大的开发工具,包括集成开发环境、调试器和性能分析工具。

  • Intel C++ Compiler (ICC):由Intel开发的C++编译器,提供了自动向量化和并行化等高级优化特性,特别适用于需要高性能计算的应用。

  • Borland C++:Borland系列编译器(包括早期的Turbo C++)曾经非常流行,尤其是在DOS和Windows 3.1时代。Borland C++ Builder Compiler是其中的一个产品,它包括了对ANSI/ISO C++语言的支持。

  • Watcom C++:Watcom C++是一个历史悠久的编译器,以其在DOS时代的高效编译而著称。现在,Watcom C++作为Open Watcom开源包发行,支持多种操作系统。

  • Digital Mars C++ Compiler:Digital Mars是一款高性能的C和C++编译器,它包括了一个集成开发环境和多种编程工具,如反汇编器和资源编译器。

  • Tiny C Compiler (TCC):TCC是一个小型的C语言编译器,虽然它主要用于C语言,但也支持一些C++特性。

  • Code::Blocks:Code::Blocks是一个轻量级的C++集成开发环境,它支持多种编译器,包括GCC和Clang,并且提供了代码自动补全、调试和版本控制等功能。

  • Qt Creator:基于Qt框架的C++集成开发环境,它提供了一套完整的工具集,用于开发跨平台的应用程序。

这些编译器各有特点,其中,GCC和Clang因其开源和跨平台特性在许多Linux发行版中被广泛采用;而MSVC则在Windows平台上提供了优秀的集成开发体验。

扩展知识:

g++gcc 是GNU编译器集合(GNU Compiler Collection,简称GCC)中的两个相关但独立的编译器,它们都用于从源代码生成可执行程序,不过它们分别针对不同的编程语言。

  • gcc

    • gcc 是GNU C Compiler的缩写,它是GCC中用于编译C语言程序的编译器。

    • 它支持多种与C语言相关的语言标准,如ANSI C(ISO C89)、ISO C99、ISO C11等。

    • gcc 也可以用于编译C++程序,但需要链接C++标准库。在某些系统中,可能存在一个名为c++的符号链接到g++,这样你就可以使用c++命令来编译C++程序。

  • g++

    • g++ 是GNU C++ Compiler的缩写,它是GCC中用于编译C++程序的编译器。

    • 它不仅包含了gcc的功能,还增加了对C++特定特性的支持,如类、模板、异常处理等。

    • g++ 默认链接C++标准库(如libstdc++),而gcc 默认链接C标准库。

因此,它们之间的具有以下关系:

  • 相同之处

    • 它们都是GCC编译器集合的一部分。

    • 它们共享底层的优化器和代码生成器,因此对于底层的C代码,两者在优化和生成的机器代码方面可能是相同的。

  • 不同之处

    • gcc 主要用于编译C语言程序,而g++ 用于编译C++程序。

    • g++ 在编译C++程序时会启用C++语言特性,并链接C++标准库,而gcc 需要额外指定链接C++标准库的选项(如-lstdc++)。

    • g++ 支持C++特有的编译选项和编译阶段,如模板元编程、名称修饰(name mangling)和RTTI(运行时类型识别)。

2 g++编译器简介

2.1 g++编译器安装

g++ 是GNU编译器集合中用于编译C++程序的编译器。如果Linux操作系统没有安装g++的话,以Ubuntu为例,参考以下命令安装g++

whccf@whccf-VirtualBox:~$ g++

Command 'g++' not found, but can be installed with:

sudo apt install g++

whccf@whccf-VirtualBox:~$ sudo apt install g++
[sudo] whccf 的密码: 
正在读取软件包列表... 完成
正在分析软件包的依赖关系树       
正在读取状态信息... 完成       
下列软件包是自动安装的并且现在不需要了:
  gir1.2-goa-1.0 gir1.2-snapd-1
使用'sudo apt autoremove'来卸载它(它们)。
将会同时安装下列软件:
  g++-7 libstdc++-7-dev
建议安装:
  g++-multilib g++-7-multilib gcc-7-doc libstdc++6-7-dbg libstdc++-7-doc
下列【新】软件包将被安装:
  g++ g++-7 libstdc++-7-dev
升级了 0 个软件包,新安装了 3 个软件包,要卸载 0 个软件包,有 0 个软件包未被升级。
需要下载 11.2 MB 的归档。
解压缩后会消耗 42.4 MB 的额外空间。
您希望继续执行吗? [Y/n] y
获取:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 libstdc++-7-dev amd64 7.5.0-3ubuntu1~18.04 [1,471 kB]
获取:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 g++-7 amd64 7.5.0-3ubuntu1~18.04 [9,697 kB]
获取:3 http://mirrors.tuna.tsinghua.edu.cn/ubuntu bionic-updates/main amd64 g++ amd64 4:7.4.0-1ubuntu2.3 [1,568 B]
已下载 11.2 MB,耗时 2秒 (5,127 kB/s)
正在选中未选择的软件包 libstdc++-7-dev:amd64。
(正在读取数据库 ... 系统当前共安装有 176694 个文件和目录。)
正准备解包 .../libstdc++-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb  ...
正在解包 libstdc++-7-dev:amd64 (7.5.0-3ubuntu1~18.04) ...
正在选中未选择的软件包 g++-7。
正准备解包 .../g++-7_7.5.0-3ubuntu1~18.04_amd64.deb  ...
正在解包 g++-7 (7.5.0-3ubuntu1~18.04) ...
正在选中未选择的软件包 g++。
正准备解包 .../g++_4%3a7.4.0-1ubuntu2.3_amd64.deb  ...
正在解包 g++ (4:7.4.0-1ubuntu2.3) ...
正在设置 libstdc++-7-dev:amd64 (7.5.0-3ubuntu1~18.04) ...
正在设置 g++-7 (7.5.0-3ubuntu1~18.04) ...
正在设置 g++ (4:7.4.0-1ubuntu2.3) ...
update-alternatives: 使用 /usr/bin/g++ 来在自动模式中提供 /usr/bin/c++ (c++)
正在处理用于 man-db (2.8.3-2ubuntu0.1) 的触发器 ...
whccf@whccf-VirtualBox:~$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 

2.2 g++常用命令

g++ 常用命令如下表所示:

功能/选项描述示例
基本编译
-c只编译不链接,生成目标文件(.og++ -c source.cpp
-o指定输出文件名g++ source.cpp -o output
多文件编译
多个源文件同时编译多个源文件g++ source1.cpp source2.cpp -o output
头文件和库
-I指定头文件搜索路径g++ -I /path/to/headers source.cpp -o output
-L指定库文件搜索路径g++ -L /path/to/libs source.cpp -o output
-l链接指定库(无需指定文件扩展名)g++ -lmylibrary source.cpp -o output
调试和优化
-g添加调试信息g++ -g source.cpp -o output
-O优化等级(0-3),默认不优化g++ -O2 source.cpp -o output
-Og优化并保留调试信息g++ -Og source.cpp -o output
警告和错误
-Wall显示所有标准警告g++ -Wall source.cpp -o output
-Wextra显示额外的警告g++ -Wextra source.cpp -o output
-Werror将警告视为错误g++ -Werror source.cpp -o output
标准和方言
-std指定 C++ 标准(如 C++11, C++14, C++17, C++20)g++ -std=c++17 source.cpp -o output
-pedantic严格按照标准进行检查g++ -pedantic source.cpp -o output
链接器选项
-static使用静态库链接g++ -static -lmylibrary source.cpp -o output
-shared生成共享库g++ -shared -o libmylibrary.so source.cpp
其他
-v显示详细的编译过程g++ -v source.cpp -o output
-E仅进行预处理,不编译或链接g++ -E source.cpp -o output.i
-S生成汇编代码g++ -S source.cpp -o output.s

2.3 g++告警选项

g++ 常用告警选项如下表所示:

告警选项描述
-Wall启用一组常用的告警选项,包括一些常见的编程错误。
-Wextra提供比 -Wall 更严格的告警集,包括一些额外的潜在问题。
-Wpedantic启用所有符合C++标准的告警,要求代码严格遵循C++标准。
-Wconversion告警所有可能的类型转换问题。
-Wsign-compare当使用有符号和无符号整数进行比较时发出告警。
-Wshadow如果局部变量遮蔽了外部变量,发出告警。
-Wunused告警所有未使用的变量、函数和参数。
-Wunused-result如果函数返回结果没有被使用,发出告警。
-Winit-self当变量被初始化为自己的值时,发出告警。
-Wmissing-include-dirs如果包含了不存在的目录,发出告警。
-Wimplicit-fallthrough在switch语句中,如果没有明确标记break或continue,发出告警。
-Wformat检查printf和scanf等格式化字符串函数的参数类型和格式字符串是否匹配。
-Wself-move当对象被移动到自身时,发出告警。
-Wdouble-promotion当浮点数被隐式提升为双精度时,发出告警。

3 C++第一份代码"hello,world"

  • VS Code编写"hello, world",源代码文件名helloworld.cpp

#include <iostream>

int main() 
{
    // 输出 "Hello, World!"
    std::cout << "Hello, World!" << std::endl;
    
    return 0;
}
  • Linux环境下,使用g++编译并生成helloworld的可执行程序

g++ -o helloworld helloworld.cpp
  • Linux环境下,执行helloworld可执行程序

./helloworld

4 代码分析

  • 预处理指令#include <iostream>

    • #include 是一个预处理指令,它告诉编译器在编译之前要包含指定的头文件。

    • <iostream> 是一个标准库头文件,它包含了C++标准库中关于输入/输出流的对象和函数的声明。 <iostream> 提供的 std::cout 对象,它代表标准输出流,用于向控制台输出数据。

  • 主函数int main()

    • main 函数是C++程序的入口点,即程序从这里开始执行。

    • intmain 函数的返回类型,表示 main 函数将返回一个整数。

    • 在操作系统中,这个返回值通常用于指示程序是否成功执行。通常,返回 0 表示程序成功执行,而非零值表示出现错误。

  • 输出语句 std::cout << "Hello, World!" << std::endl;

    • std::cout 是一个输出流对象,用于向标准输出(通常是控制台或终端)发送数据。

    • << 是一个插入运算符,用于将数据发送到输出流。

    • "Hello, World!" 是一个字符串字面量,表示要输出的文本内容。

    • std::endl 是一个流操纵符,它向输出流插入一个换行符,并刷新输出缓冲区,确保数据立即被显示在控制台上。

  • 返回值 return 0;

    • return 语句用于从函数中返回一个值。

    • main 函数中,return 0; 表示程序成功执行,并返回状态码 0

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值