C++14编译触发-Wc++98报错及跨平台差异问题咨询
问题解答
1. 已配置C14仍抛出C98兼容性错误的原因
这类C98兼容报错和你当前指定的编译标准没有直接关系。-Wc++98-compat系列告警的作用是**额外检查代码是否符合C98语法规范**,只要开启了这个告警项,不管你用C14还是更高版本编译,编译器都会把所有C98不支持的语法(比如constexpr、long long、C14才允许的constexpr函数逻辑)标记出来。
你遇到这个问题的直接原因是:Windows环境下你用的Clang 7.0.0(clang-cl前端),-Wall选项默认就包含了全套C98兼容性检查项,再加上你开了-Werror把所有告警转成错误,自然会报这类问题。
另外你的CMake配置存在不严谨的地方:直接对CMAKE_CXX_FLAGS赋值会覆盖CMake自动生成的编译参数,虽然你验证过实际确实在按C++14编译,但这套写法没有触发Clang自动关闭旧版本兼容检查的逻辑。
2. 相同配置Linux环境无报错的原因
核心差异来自两点:Clang版本差异、不同平台下-Wall的默认告警集合不同:
- 你Linux环境用的是Clang 5.0.1,这个版本的
-Wall默认不包含任何-Wc++98-compat相关的告警项,这类检查必须手动显式开启才会生效。 - Windows端用的是适配Visual Studio的clang-cl前端,本身为了兼容MSVC的项目适配逻辑,
-Wall的默认告警集合和原生Unix版Clang不一样,从Clang 6开始clang-cl的-Wall就默认带上了C98兼容检查,你用的7.0版本刚好命中这个默认规则。
另外原生Linux版Clang会根据你指定的C编译标准,自动屏蔽对应旧版本兼容的冗余告警,但clang-cl不会做这个自动处理。
修复方法
如果你的项目不需要兼容C++98,直接在告警列表里追加三个关闭项即可:
set(COMMON_FLAGS -Wfloat-conversion -Wsign-compare -Wsign-conversion -Wbitfield-enum-conversion -Wshorten-64-to-32 -Wstring-conversion -Werror -Wall -Wextra -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-c++98-c++11-compat)
更规范的CMake写法是不要直接全局覆盖CMAKE_CXX_FLAGS,优先用target_compile_features指定目标的C++标准要求,用target_compile_options给具体目标加编译选项,避免覆盖编译器默认的合理参数。
内容的提问来源于stack exchange,提问作者Preethi Vaidyanathan
相关产品推荐
相关产品推荐

