现代C++编程:从入门到实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.2 编译器工具链

为C++程序编写代码之后,下一步就是将代码转换为可执行程序。编译器工具链是一个包含三种元素的集合,它们按顺序运行,将代码转换为可执行程序:

❑ 首先,由预处理器(preprocessor)执行基本的源代码转换。例如,#include<cstdio>是一种预处理指令,它指示预处理器将cstdio程序库引入源代码中。当预处理器完成源代码的处理之后,它会生成一个编译单元。每一个编译单元都会被传给编译器去处理。

❑ 其次,由编译器(compiler)读入编译单元,生成一个目标文件。目标文件包含一种叫作目标代码的中间格式数据。这些文件中的数据和指令都是中间格式的,它们对人类来说不可读。编译器一次转换一个编译单元,所以每一个编译单元都对应一个目标文件。

❑ 最后,由链接器(linker)从目标文件中生成最终程序。链接器也负责寻找包含在源代码中的程序库。例如,当编译代码清单1-1中的程序时,链接器会找到cstdio程序库,并且引入所有必要的信息来使用printf函数。注意,cstdio头文件(header)不同于cstdio程序库。头文件包含使用程序库的方法的信息。第21章将介绍更多关于程序库和源代码组织结构的知识。

1.2.1 设置开发环境

所有的C++开发环境都包含一套编辑源代码的编辑器和将源代码转换为程序的编译器工具链。通常,开发环境也包含调试器,它是一种可以让我们一行行地执行程序的代码以寻找错误的无价工具。

当所有这些工具——文本编辑器、编译器工具链和调试器——打包成一个程序时,我们称这个程序为交互式开发环境(Interactive Development Environment,IDE)。IDE对初学者和老手的效率提升都有巨大作用。

注意 不幸的是,C++并没有一个可以交互地执行C++代码片段的解释器,这和Python、Ruby和JavaScript等语言不同,它们都有解释器。一些Web应用程序允许测试和分享一些小的C++代码片段,例如Wandbox(https://wandbox.org/)——该网站可以让你编译和运行代码,以及Matt Godbolt的Compiler Explorer(https://www.godbolt.org/)——该网站可以让你检查源代码生成的汇编代码。这两者都可以在各种编译器和系统上运行。

每一个操作系统都有自己的源代码编辑器和编译器工具链,所以本节将按照操作系统组织。你可以直接跳到对应的操作系统部分。

1.2.2 Windows 10以及后续版本:Visual Studio

编写本书时,Windows最流行的C++编译器是微软Visual C++编译器(MicroSoft Visual C++ Compiler,MSVC)。获取MSVC最简单的方法就是按照下列步骤安装Visual Studio 2017 IDE:

1)下载Visual Studio 2017社区版(https://ccc.codes/)。

2)运行安装包,如果有必要,请允许它进行更新。

3)在Installing Visual Studio界面,请确保Desktop Development with C++ Workload被选中了。

4)单击Install(安装)按钮安装Visual Studio 2017以及MSVC。

5)单击Launch(运行)按钮运行Visual Studio 2017。整个过程可能需要花费几小时,具体取决于机器的速度和所选的选项。典型的安装空间需要20~50GB。

设置新项目的步骤如下:

1)选择File(文件)→New(新建)→Project(项目)。

2)在Installed(已安装)下,单击Visual C++并且选择Default(默认)。然后,在中间的面板中选择Empty Project(空项目)。

3)输入hello作为项目的名称。这时,窗口应该看起来和图1-1类似,但是Location可能不同,具体取决于用户名。单击OK(确认)。

图1-1 Visual Studio 2017新建项目窗口

4)在工作空间左边的Solution Explorer(解决方案资源管理器)中,右键单击Source Files(源文件)并且选择Add(添加)→Existing Item(现有项),如图1-2所示。

图1-2 向Visual Studio 2017项目中添加现有源文件

5)选择之前在代码清单1-1中创建的文件main.cpp。如果还没有创建这个文件,则选择New Item(新建)而不是Existing Item(现有项),将该文件命名为main.cpp并将代码清单1-1的内容输入到相应的编辑器窗口中。

6)选择Build(生成)→Build Solution(生成解决方案)。如果输出窗口出现任何错误,请确认输入的内容和代码清单1-1中的一致。如果仍然出现错误,请仔细检查这些错误内容来获取提示。

7)选择Debug(调试)→Start Without Debugging(开始执行,不调试)或者按下<Ctrl+F5>键来运行程序。此时,Hello, world!字样将被打印在控制台窗口中(紧接着,会有按任意键继续的字样)。

1.2.3 macOS:Xcode

如果使用的是macOS,那么应该安装Xcode开发环境:

1)打开App Store(应用商店)。

2)搜索并安装Xcode开发环境。安装过程可能会花费一个多小时,具体取决于机器和互联网连接的速度。当安装完成时,打开Terminal(终端)并转到保存main.cpp的目录。

3)在终端中输入clang++main.cpp-o hello来编译程序。-o选项指示工具链将结果输出到哪里。如果出现了编译错误,请检查之前输入的程序内容是否正确。

4)在终端中输入./hello来运行程序。此时,Hello, world!字样会出现在屏幕上。

为了编译和运行程序,请打开Xcode开发环境并且按以下步骤执行:

1)选择File(文件)→New(新建)→Project(项目)。

2)选择macOS→Command Line Tool(命令行工具)并单击Next(下一步)。在下一个对话框中,可以选择在哪里创建项目的文件。现在,接受默认设置并且单击Create(创建)。

3)将项目命名为hello并将其类型设置为C++,参见图1-3。

图1-3 Xcode中新建项目对话框

4)现在,将代码清单1-1中的代码导入项目中。一个简单的办法就是将main.cpp的内容复制、粘贴到项目的main.cpp。另一个办法就是使用Finder进行替换。(在创建新项目时通常不需要处理这个问题。这只是本教程为了应付多个操作系统环境的特殊步骤。)

5)单击Run(运行)。

1.2.4 Linux和GCC

对于Linux,可以选择两种C++编译器:GCC和Clang。在编写本书时,最新的GCC稳定版是9.1,最新的Clang版本是8.0.0。这一节将介绍如何安装它们。有时候,用户会觉得其中一个的错误信息比另一个的更有帮助。

注意 GCC表示GNU编译器套件(GNU Compiler Collection)。GNU的发音是“guh-NEW”,意指“GNU’s Not Unix!”(GNU不是Unix)。GNU是一个类Unix的操作系统,它包含一系列计算机软件。

你可以尝试通过操作系统的包管理器来安装GCC和Clang,但是请注意,默认的软件仓库可能只有老版本,它们可能并不支持C++17。如果不支持C++17,本书中的一些例子可能没办法编译,所以你需要安装新版本的GCC和Clang。为了简洁,这一章会介绍如何在Debian上以及如何从源码安装它们。你可以自行研究如何在自己选择的Linux系统上执行这些必要操作,也可以直接使用本章提到的操作系统来设置开发环境。

1.在Debian上安装GCC和Clang

考虑到个人包管理存档(Personal Package Archives,PPA)的状态,当你阅读本章的时候,你可以用Debian的包管理工具APT(Advanced Package Tool)直接安装GCC 8.1以及Clang 6.0。本小节将展示如何在Ubuntu 18.04(编写本书时最新的Ubuntu LTS版本)上安装GCC和Clang:

1)打开终端。

2)更新并升级已经安装的包:

3)安装GCC 8和Clang 6.0:

4)测试GCC和Clang:

如果以上任一命令报错说该命令没有找到,则相应的编译器没有安装成功。尝试搜索报错信息,尤其是在包管理器的文档中和论坛上进行搜索。

2.从源码安装GCC

如果无法在包管理器中找到最新版的GCC或者Clang(或者Unix变体根本没有包管理器),那么可以尝试从源码安装GCC。注意,这会花费很多时间(长达几小时),并且可能需要手动处理不少问题:安装过程中常常会遇到错误,因而需要研究如何解决。请参考https://gcc.gnu.org/上的步骤来安装GCC。本小节总结了该网站上的文档。

注意 为了简洁,该教程不会详细讲解Clang的安装,有关Clang的更多信息,请参考https://clang.llvm.org/。

从源码安装GCC 8.1,请遵照以下步骤:

1)打开终端。

2)更新并升级已经安装的包。例如,使用APT需要执行以下命令:

3)从https://gcc.gnu.org/mirrors.html选择一个镜像源,下载文件gcc-8.1.0.tar.gz和gcc-8.1.0.tar.gz.sig。这些文件可以在releases/gcc-8.1.0下找到。

4)检查包的完整性(可选)。首先,导入相应的GnuPG公钥。公钥可以在镜像网站找到。例如:

校验下载的包:

上面的警告的意思是机器还没有将签名者的证书标记为受信证书。要检查签名的确属于包的拥有者,需要用其他的办法校验签名的密钥(例如,亲自与其本人见面或者使用其他渠道校验主密钥的指纹)。想要了解更多GNU隐私保护(GNU Privacy Guard,GPG),请参阅Michael W. Lucas撰写的PGP& GPG: Email for the Practical Paranoid或者浏览https://gnupg.org/download/integrity_check.html获取有关GPG完整性检查设施的具体信息。

5)解压包(该命令可能需要执行几分钟):

6)切换到刚刚创建的gcc-8.1.0文件夹:

7)下载GCC的安装依赖项:

8)用以下命令配置GCC:

相关配置指令见https://gcc.gnu.org/install/configure.html。

9)构建GCC二进制文件(可能晚上做比较好,因为这个过程需要几小时):

完整的指令介绍见https://gcc.gnu.org/install/build.html。

10)测试GCC二进制文件是否正确构建:

完整的指令介绍见https://gcc.gnu.org/install/test.html。

11)安装GCC:

该命令会将一些二进制文件放到操作系统的可执行文件的默认目录,一般是/usr/local/bin。完整的指令介绍见https://gcc.gnu.org/install/。

12)通过以下命令来检查GCC是否正确安装:

如果遇到命令无法找到的错误,则说明没有安装成功。请参考位于https://gcc.gnu.org/ml/gcc-help/的gcc-help邮件列表来寻找解答。

注意 如果想要给冗长的x86_64-pc-linux-gnu-gcc-8.1.0取个别名,如g++8,则可以使用以下命令:

13)切换到存放main.cpp的目录,然后用GCC编译程序:

14)-o选项是可选的,它告诉编译器如何命名最终的程序。因为给程序取名hello,所以可以输入./hello来执行程序。如果碰到任何编译错误,请确保输入的命令正确。(编译错误可以帮助你定位哪里出错了。)

1.2.5 文本编辑器

如果不想使用前面提到的IDE,也可以使用简单的文本编辑器[例如Notepad(Windows)、TextEdit(Mac)或者Vim(Linux)]来写C++代码,但是有一些优秀的编辑器是专门为C++开发而设计的。建议选择对自己来说最高效的开发环境。

如果你使用的是Windows或者macOS,那么你已经有了一个高质量、全功能的IDE了,即Visual Studio和Xcode。对于Linux,则可以选择Qt Creator(https://www.qt.io/ide/)、Eclipse CDT(https:// eclipse.org/cdt/)和JetBrains的CLion(https://www.jetbrains.com/clion/)。如果使用Vim或者Emacs,那么可以找到大量的C++插件。

注意 如果跨平台C++开发对你来说很重要,那么强烈推荐你试一下JetBrains的CLion。尽管CLion是付费产品,和很多其他编辑器不一样,但是截至编写本书时,JetBrains也有折扣,甚至免费授权给学生及开源软件维护人员。