0-11 配置编译器:警告和错误级别
编写程序时,编译器会检查您是否遵循了C++语言规则(前提是您已关闭编译器扩展功能,详见第0.10课——配置编译器:编译器扩展)。若您的操作明确违反语言规则,则程序将被判定为格式错误ill-formed。
大多数情况下,当编译器遇到问题时会输出诊断信息diagnostic message(通常简称诊断diagnostic)。C++标准并未规定诊断信息的分类方式、措辞规范或这些问题对编译过程的影响。但现代编译器普遍采用以下约定:
-
诊断错误
diagnostic error(简称错误error)表示编译器决定终止编译,因为无法继续编译或认为错误严重到必须停止。编译器生成的诊断错误通常称为编译错误compilation errors、编译器错误compiler errors或编译问题compile errors。 -
诊断警告
diagnostic warning(简称警告warning)表示编译器决定不终止编译。此类情况下问题将被忽略,编译继续进行。
关键洞察:
编译器会判定非阻塞问题属于警告还是错误。虽然它们通常在分类上保持一致,但在某些情况下,编译器可能出现分歧——针对同一问题,一个编译器可能报错,另一个编译器则仅发出警告。
为帮助您定位问题所在,诊断信息通常包含编译器发现问题的文件名和行号,以及预期结果与实际结果的对比说明。实际问题可能出现在该行或前面的行。解决导致诊断信息的问题后,可尝试重新编译以确认相关诊断信息是否不再出现。
在某些情况下,编译器可能识别出符合语言规则但可能存在问题的代码。此时编译器会发出警告,提醒程序员存在异常情况。这类问题可通过两种方式解决:修正警告所指出的问题,或重写问题代码行以消除警告。
对于高级读者:
我们在第7.7节——外部链接与变量前向声明中展示了一个技术上合法但会被现代编译器视为可疑的语句示例。在极少数情况下,可能需要明确告知编译器对特定代码行不生成警告。C++虽未提供官方解决方案,但许多编译器(包括Visual Studio和GCC)通过非移植性#pragma指令实现了临时禁用警告的功能。
最佳实践:
不要让警告堆积如山。遇到警告时应立即处理(如同处理错误一般)。否则,关于严重问题的警告可能会淹没在非严重问题的警告中。
若链接过程中出现无法解决的问题,链接器也可能生成诊断错误。
提高警告级别
默认情况下,大多数编译器只会针对最明显的问题生成警告。但您可以要求编译器更积极地提供警告,这通常是个好主意。
最佳实践:
请提高警告级别,尤其是在学习阶段。额外的诊断信息有助于识别可能导致程序故障的编程错误。
对于Visual Studio 用户:
若需提高警告级别,请在解决方案资源管理器窗口中右键单击项目名称,然后选择“属性”:
在项目对话框中,首先确保配置字段设置为所有配置。
然后选择 C/C++ > 常规选项卡,并将警告级别设置为级别 4 (/W4):
注意:请勿选择启用所有警告(/Wall),否则您将被C++标准库生成的警告淹没。Visual Studio默认禁用了有符号/无符号转换警告,而这些警告非常有用。因此,若您使用的是Visual Studio 2019或更高版本,请启用这些警告:
- 在C/C++ > 命令行选项卡的附加选项下,添加/w44365。此操作指示编译器以警告级别4(即上文启用的级别)启用有符号/无符号转换警告。
- 在C/C++ > 外部包含选项卡中,将外部头文件警告级别设置为Level3(/external:W3)。此操作指示编译器以警告级别3(而非4)编译标准库头文件,避免编译这些头文件时触发警告。
上图未显示“外部包含”选项卡,但在VS Community 2019及更高版本中位于“浏览信息”与“高级”选项卡之间。请参阅此链接,其中包含近期截取的包含“外部包含”选项卡的对话框图片。
若上述设置正确,编译以下程序应生成警告C4365:
void foo(int) { } int main() { unsigned int x { 5 }; foo(x); return 0; }若未看到警告信息,请同时检查“输出”和“错误列表”选项卡(若存在)。
对于Code::Blocks 用户:
从“设置”菜单 > “编译器” > “编译器设置”选项卡中,找到并勾选与 -Wall、-Weffc++ 和 -Wextra 相关的选项:
然后转到“其他编译器选项”选项卡,并在以下文本编辑区域中添加 -Wconversion -Wsign-conversion:
注:-Werror 参数的说明如下。
对于 gcc 用户:
请在命令行中添加以下标志:
-Wall -Weffc++ -Wextra -Wconversion -Wsign-conversion
对于VS Code 用户:
打开 tasks.json 文件,找到“args”部分,然后在该部分内定位到“${file}”这一行。
在“${file}”行上方,添加包含以下命令的新行(每行一条):“-Wall”, “-Weffc++”, “-Wextra”, “-Wconversion”, “-Wsign-conversion”,
将警告视为错误
您还可以指示编译器将所有警告视为错误(此时编译器在发现任何警告时都会停止编译)。这是强制执行修复所有警告建议的有效方式(若您缺乏自律性——而我们大多数人确实如此)。
最佳实践:
启用“将警告视为错误”功能。这将迫使你解决所有引发警告的问题。
对于Visual Studio 用户:
若要将警告视为错误,请在“解决方案资源管理器”窗口中右键单击项目名称,然后选择“属性”:
在项目对话框中,首先确保配置字段设置为所有配置。
然后选择 C/C++ > 常规选项卡,并将警告视为错误设置为是 (/WX)。
对于Code::Blocks 用户:
从“设置”菜单 > “编译器” > “其他编译器选项”选项卡中,在文本编辑区域添加 -Werror:

对于 gcc 用户:
请在命令行中添加以下标志:-Werror
对于VS Code 用户:
在 tasks.json 文件中,于“${file}”之前按以下格式逐行添加以下标志:
“-Werror”,







浙公网安备 33010602011771号