默认关闭的编译器警告

编译器支持默认关闭的警告(因大多数开发人员认为它们没有用处而关闭)。 在某些情况下,这些警告与样式选择或旧代码中的常用习语相关。 其他警告与使用相应语言的 Microsoft 扩展相关。 某些警告会指明程序员经常做出错误假设(这可能会导致意外或未定义的行为)的区域。 如果启用所有这些警告,则其中一些警告可能会在库标头中多次出现。 C 运行时库和 C++ 标准库不会在警告级别 /W4 发出警告。

启用默认关闭的警告

可使用以下选项之一来启用一般情况下默认关闭的警告:

  • #pragma warning(default :warning_number)

    指定的警告 (warning_number) 在其默认级别启用。 该警告的文档包含该警告的默认级别。

  • #pragma warning(warning_level:warning_number)

    指定的警告 (warning_number) 在指定的级别 (warning_level) 启用

  • /Wall

    /Wall 将启用默认情况下禁用的所有警告。 如果使用此选项,则可以使用 /wd 选项关闭单个警告。

  • nnnn/wL

    此选项在 L 级别启用警告 nnnn

默认关闭的警告

Visual Studio 2015 及更高版本

Visual Studio 2015 和更高版本中默认会关闭以下警告:

警告 Message
C4061(级别 4) 大小写标签未显式处理枚举“enumeration”的开关中的枚举器“identifier”
C4062(级别 4) 未处理枚举“enumeration”的开关中的枚举器“identifier”
C4165(级别 1) “HRESULT”正在转换为“bool”;是否确认要这样操作?
C4191(级别 3) “operator”: 从“type of expression”到“type required”的不安全转换
C4242(级别 4) “identifier”: 从“type1”转换到“type2”,可能丢失数据
C4254(级别 4) “operator”: 从“type1”转换到“type2”,可能丢失数据
C4255(级别 4) “function”: 未给出函数原型: 将“()”转换为“(void)”
C4263(级别 4) “function”:成员函数不替代任何基类虚成员函数
C4264(级别 1) “virtual_function”: 任何重写都不可用于来自基“class”的虚拟成员函数;函数已被隐藏
C4265(级别 3) “class”: 类具有虚拟函数,但析构函数不是虚拟的
C4266(级别 4) “function”: 无法从基本“type”重写虚拟成员函数;函数被隐藏
C4287(级别 3) “operator”: 无符号/负常量不匹配
C4289(级别 4) 使用了非标准扩展: “var”: 在 for 循环中声明的循环控制变量用在了 for 循环范围外
C4296(级别 4) “operator”: 表达式始终为 false
C4339(级别 4) “type”: 在 CLR 元数据中检测到使用了未定义的类型 - 使用此类型可能导致运行时异常
C4342(级别 1) 行为更改: 调用了“function”,但在以前版本中调用的是成员运算符
C4350(级别 1) 行为变更:调用了“member1”而不是“member2”
C4355 “this”: 用于基成员初始值设定项列表
C4365(级别 4) “action”: 从“type_1”转换到“type_2”,有符号/无符号不匹配
C4370(级别 3) 为了更好地封装,类的布局与早期版本的编译器已有所不同
C4371(级别 3) “class-name”:为了更好地封装成员“member”,类的布局可能与早期版本的编译器已有所不同
C4388(级别 4) 有符号/无符号不匹配
C4412(级别 2) “function”: 函数签名包含类型“type”;在纯代码与混合代码或本机代码之间传递 C++ 对象是不安全的
C4426(级别 1) 包含标头后更改了优化标记,可能是由于 #pragma optimize() 14.1
C4435(级别 4) “class1”:/vd2 下的对象布局将因虚拟基“class2”而更改
C4437(级别 4) 从虚拟基“class1”到“class2'”的 dynamic_cast 在某些上下文中可能会失败
C4444(级别 3) 顶级“__unaligned”没有在该上下文中实现。
C4464(级别 4) 相对 include 路径包含“..”
C4471(级别 4) 无范围枚举的前向声明必须有基础类型(假定为 int) Perm
C4472(级别 1) “identifier”是本机枚举: 添加访问说明符(private/public)以声明托管枚举
C4514(级别 4) “function”:已删除未引用的内联函数
C4536(级别 4) “type name”: 类型名超出了“limit”个字符的元数据限制
C4545(级别 1) 逗号前的表达式计算为缺少自变量列表的函数
C4546(级别 1) 逗号前的函数调用缺少自变量列表
C4547(级别 1) “operator”: 逗号前的运算符不起任何作用;需要带副作用的运算符
C4548(级别 1) 逗号前的表达式不起任何作用;应输入带副作用的表达式
C4549(级别 1) “operator1”: 逗号前的运算符不起任何作用;是否是有意使用“operator2”的?
C4555(级别 1) 表达式无效;应输入带副作用的表达式
C4557(级别 3) “__assume”包含效果“effect”
C4571(级别 4) 信息: 自 Visual C++ 7.1 之后,catch(...) 语义发生了变化;不再捕获结构化的异常(SEH)
C4574(级别 4) “identifier”被定义为“0”: 你是否希望使用“#if identifier”?
C4577(级别 1) 在未指定异常处理模式的情况下使用了“noexcept”;不一定会在异常时终止。 指定 /EHsc
C4582(级别 4) “type”: 构造函数未隐式调用
C4583(级别 4) “type”: 析构函数未隐式调用
C4587(级别 1) “anonymous_structure”: 行为变更: 不再隐式调用构造函数
C4588(级别 1) “anonymous_structure”:行为变更:不再隐式调用析构函数
C4596(级别 4) “identifier”: 成员声明中的非法限定名 14.3Perm
C4598(级别 1 和级别 3) “#include "header"”: 预编译标头中的标头编号 header-number 与该位置的当前编译不匹配 14.3
C4599(级别 3) “optionpath”:命令行参数编号 arg_number 与预编译标头不匹配 14.3
C4605(级别 1) “/Dmacro”在当前命令行上指定,但未在生成预编译标头时指定
C4608(级别 3) “union_member”已由初始化表达式列表中的另一个联合成员“union_member”初始化 Perm
C4619(级别 3) #pragma warning: 无警告编号“number”
C4623(级别 4) “derived class”: 未能生成默认构造函数,因为基类默认构造函数不可访问
C4625(级别 4) “derived class”: 未能生成复制构造函数,因为基类复制构造函数不可访问
C4626(级别 4) “derived class”: 未能生成赋值运算符,因为基类赋值运算符不可访问
C4628(级别 1) -Ze 不支持二合字母。 字符序列“digraph”未解释为“char”的替换标记
C4640(级别 3) “instance”: 本地静态对象的结构是非线程安全的
C4643(级别 4) C++ 标准不允许转发命名空间 std 中的声明“identifier”15.8
C4647(级别 3) 行为更改: __is_pod(type) 在各种版本中具有不同的值
C4654(级别 4) 将忽略放置在预编译标头行的 include 语句前面的代码。 将代码添加到预编译标头。 14.1
C4668(级别 4) 没有将“symbol”定义为预处理器宏,用“0”替换“directives”
C4682(级别 4) “symbol”: 未指定方向参数特性,默认为 [in]
C4686(级别 3) “user-defined type”: 行为可能有更改,UDT 中的更改返回调用约定
C4692(级别 1) “function”: 非私有成员的签名包含程序集私有本机类型“native_type”
C4710(级别 4) “function”: 函数未内联
C4738(级别 3) 将 32 位浮点型结果存储在内存中,可能会降低性能
C4746 “expression”的可变访问受 /volatile:<iso|ms> 设置的限制;请考虑使用 __iso_volatile_load/store 内部函数
C4749(级别 4) 有条件支持: 应用于非标准布局类型“type”的 offsetof
C4767(级别 4) 节名称“symbol”的长度超过 8 个字符,并将由链接器截断
C4774(级别 4) “string”: 参数 number 中应存在的格式字符串不为字符串字面量
C4777(级别 4) “function”: 格式字符串“string”需要类型为“type1”的参数,但可变参数 number 的类型为“type2”
C4786(级别 3) “symbol”: 对象名称在调试信息中被截断为“number”个字符
C4800(级别 4) 从“type”隐式转换为布尔。 可能的信息丢失 16.0
C4820(级别 4) “member_name”构造后添加了“bytes”字节填充
C4822(级别 1) “member”: 局部类成员函数没有函数体
C4826(级别 2) 从“type1”到“type2”的转换是带符号的扩展转换。 这可能导致意外的运行时行为。
C4837(级别 4) 检测到三元组:“??character”已替换为“character”
C4841(级别 4) 使用的非标准扩展: offsetof 中使用的复合成员指示符
C4842(级别 4) "offsetof" 应用于使用多重继承的类型,但不保证其结果在各编译器版本之间保持一致
C4866(级别 4) “file(line_number)”编译器可能不会在对 operator 的调用中强制执行从左到右计算顺序
C4868(级别 4) “file(line_number)”编译器可能不会在用大括号括起的初始化表达式列表中强制执行从左到右计算顺序
C4905(级别 1) 宽字符串强制转换为“LPSTR”
C4906(级别 1) 字符串强制转换为“LPWSTR”
C4917(级别 1) “declarator”: GUID 只能与类、接口或命名空间相关联
C4928(级别 1) 副本初始化非法;隐式应用了多个用户定义的转换
C4931(级别 4) 我们假定类型库是为 number 位指针生成的
C4946(级别 1) reinterpret_cast 在相关类之间使用:“class1”和“class2”
C4962 “function”: 已禁用按配置文件优化,原因在于优化导致了配置数据文件不一致
C4986(级别 4) “symbol”: 异常规范与前面的声明不匹配
C4987(级别 4) 使用了非标准扩展:“throw (...)”
C4988(级别 4) “symbol”: 在类/函数范围外声明了变量
C5022 “type”:指定了多个移动构造函数
C5023 “type”: 指定了多个移动赋值运算符
C5024(级别 4) “type”: 已将移动构造函数隐式定义为已删除
C5025(级别 4) “type”: 已将移动赋值运算符隐式定义为已删除
C5026(级别 1 和级别 4) “type”: 已将移动构造函数隐式定义为已删除
C5027(级别 1 和级别 4) “type”: 已将移动赋值运算符隐式定义为已删除
C5029(级别 4) 使用了非标准扩展: C++ 中的对齐属性只适用于变量、数据成员和标记类型
C5031(级别 4) #pragma warning(pop): 可能不匹配,正在弹出的警告状态已推送到其他文件 14.1
C5032(级别 4) 已检测到 #pragma warning(push),但未检测到相应的 #pragma warning(pop) 14.1

Visual Studio 2017 及更高版本

Visual Studio 2017 及更高版本中默认关闭以下警告:

警告 Message
C5034 使用内部“intrinsic”会导致函数 function-name 被编译为来宾代码15.3
C5035 使用功能“feature”会导致函数 function-name 被编译为来宾代码15.3
C5036(级别 1) 在将 /hybrid:x86arm64 从“type1”编译为“type2”时的 varargs 函数指针转换 15.3
C5038(级别 4) 数据成员“member1”将在数据成员“member2”后初始化15.3
C5039(级别 4) “function”:指向可能引发传递给 -EHc 下 extern C 函数的函数的指针或引用。。 如果此函数引发异常,则可能发生未定义的行为。 15.5
C5041(级别 4) “member-name”: 不需要对 constexpr 静态数据成员进行外部定义,且在 C++ 17 中弃用了该类定义15.2
C5042(级别 3) “function”: 不能将在块范围的函数声明指定为标准 C++ 中的“inline”;删除“inline”说明符 15.5
C5045 如果指定了 /Qspectre 开关,编译器会插入内存负载的 Spectre 缓解 15.7

Visual Studio 2019 及更高版本

Visual Studio 2019 及更高版本中默认关闭以下警告:

警告 Message
C5052(级别 3) 关键字“keyword-name”已引入 C++ 版本,并且需要使用“option”命令行选项16.1
C5204(级别 3) 包含虚拟函数的类具有非虚简单析构函数。 16.5
C5214(级别 4) C++20 中已弃用将“keyword”应用于具有可变限定类型的操作数 16.7
C5215(级别 4) C++20 中已弃用具有可变限定类型的函数参数“function-parameter”16.7
C5216(级别 4) C++20 中已弃用可变限定返回类型“return-type”16.7
C5217(级别 4) C++20 中已弃用包含可变项的结构化绑定声明 16.7
C5219(级别 2) 从“type-1”隐式转换到“type-2”,可能会丢失数据16.7
C5220(级别 4) “member”: 具有可变限定类型的非静态数据成员不再意味着
编译器生成的 copy/move 构造函数和 copy/move 赋值运算符不简单 16.7
C5233(级别 4) 未使用显式 lambda 捕获“identifier”16.10
C5240(级别 4) “attribute-name”: 在此语法位置将忽略属性16.10
C5243(级别 1) “type-name”: 由于 ABI 限制,使用不完整的类“class-name”可能会导致潜在的一个定义规则冲突16.10
C5245(级别 4) “function”:已删除具有内部链接的未引用函数
C5246(级别 1) “member”: 子对象的初始化应括在大括号内16.10
C5247(级别 1) 节“section-name”是为 C++ 动态初始化保留的。 手动创建节会干扰 C++ 动态初始化,并可能导致未定义的行为 16.11
C5248(级别 1) 节“section-name”是为 C++ 动态初始化保留的。 手动放入节中的变量可能已优化,并且其相对于编译器生成的动态初始化表达式的顺序未指定 16.11

Visual Studio 2022 及更高版本

Visual Studio 2022 及更高版本中默认关闭以下警告:

警告 Message
C5249(级别 1) 类型为“enumeration_name”的“bitfield”已命名枚举器,其值不能以给定的位字段宽度“bitfield_width”表示17.0
C5250(级别 3) “function_name”:未声明内部函数17.0
C5251(级别 4) segment-name 在包含标头后更改 17.1
C5254(级别 4) 语言功能“简要静态断言”需要编译器标志“/std:c++17”17.1
C5256(级别 1) “enumeration”:具有固定基础类型的枚举的非定义声明只能作为独立声明 17.2
C5258(级别 4) 此用途不需要显式捕获“symbol”17.2
C5259(级别 4) “specialized-type”:显式专用化需要“template <>17.3
C5262(级别 1,错误) 此处发生隐式下沉;是否缺少 break 语句? 在事例之间有意省略 break 语句时使用 [[fallthrough]]17.4
C5263(级别 4) 对临时对象调用“std::move”会阻止复制省略17.4
C5264(级别 4) “variable-name”:未使用“const”变量 17.4
C5266(级别 4) 返回类型的“const”限定符不起作用 17.6
C5267(等级 4) 不推荐使用“type”的隐式复制构造函数/赋值运算符的定义,因为它具有用户提供的赋值运算符/复制构造函数17.7

14.1 从 Visual Studio 2015 Update 1 开始提供此警告。
14.3 从 Visual Studio 2015 Update 3 开始提供此警告。
15.2 从 Visual Studio 2017 版本 15.2 开始提供此警告。
15.3 从 Visual Studio 2017 版本 15.3 开始提供此警告。
15.5 从 Visual Studio 2017 版本 15.5 开始提供此警告。
15.7 从 Visual Studio 2017 版本 15.7 开始提供此警告。
15.8 从 Visual Studio 2017 版本 15.8 开始提供此警告。
16.0 从 Visual Studio 2019 RTM 开始提供此警告。
16.5 从 Visual Studio 2019 版本 16.5 开始提供此警告。
16.7 从 Visual Studio 2019 版本 16.7 开始提供此警告。
16.10 从 Visual Studio 2019 版本 16.10 开始提供此警告。
16.11 从 Visual Studio 2019 版本 16.11 开始提供此警告。
17.0 从 Visual Studio 2022 版本 17.0 开始提供此警告。
17.1 从 Visual Studio 2022 版本 17.1 开始提供此警告。
17.2 从 Visual Studio 2022 版本 17.2 开始提供此警告。
17.3 从 Visual Studio 2022 版本 17.3 开始提供此警告。
17.4 从 Visual Studio 2022 版本 17.4 开始提供此警告。
17.5 从 Visual Studio 2022 版本 17.5 开始提供此警告。
17.6 从 Visual Studio 2022 版本 17.6 开始提供此警告。
17.7 从 Visual Studio 2022 版本 17.7 开始提供此警告。
Perm 除非设置了 /permissive- 编译器选项,否则会关闭此警告。

早期版本默认关闭的警告

以下警告在 Visual Studio 2015 版本 15.3 中默认已关闭,在 Visual Studio 2015 版本 15.5 中已启用:

警告 消息
C4768 忽略链接规范前面的 __declspec 属性

以下警告在 Visual Studio 2015 之前的编译器版本中默认已关闭:

警告 Message
C4302(级别 2) “conversion”: 从“type1”到“type2”截断
C4311(级别 1) “variable”: 从“type”到“type”的指针截断
C4312(级别 1) “operation”:从“type1”转换到更大的“type2”
C4319(级别 1) “operator”:将“type1”零扩展到更大的“type2”

以下警告在 Visual Studio 2012 之前的编译器版本中默认已关闭:

警告 Message
C4431(级别 4) 缺少类型说明符 - 假定为 int。 注意: C 不再支持默认的 int

另请参阅

warning pragma