使用openMVS库,在VS2022中启用c++17标准编译仍然报错

使用openMVS库,在VS2022中启用c++17标准编译仍然报错

现象

项目中引用了某些开源库(例如openmvs2.1.0),编译时要求启用编译器对c++17的支持。

没问题!大家都知道在下图所示的位置调整C++语言标准:

但是,打开开关之后编译,依然报错:

这可真是一个令人百思不得其解的错误啊。报错的文件是官方的头文件type_traits,双击之后跳转的错误位置也看不出个所以然。

这下头大了。不过,之前编译openmvs库时,用的是同一版本的VS编译器,怎么就成功了呢?于是查看vcpkg自动编译openmvs时用cmake配置生成的CMakeCache.txt中的编译选项,才找到了真正原因,如下图所示:

图中标出来的选项是cmake生成的,并不常见,至少在VS2022中没有提供开关,而只能靠用户手动输入到属性页、C/C++、命令行的其他选项框中。

报错原因:__cplusplus

__cplusplus宏是MSVC编译器预定义的宏,它的值是许多语法特性的开关。前面讲了,要启用c++17标准,就在C++语言标准设置好即可。然而,__cplusplus宏值不随上面的C++语言标准/std 选项)设置而改变,需要同时添加:/Zc:__cplusplus编译选项,才能随着语言标准而改变,如下表所示:

/Zc:__cplusplus 选项 /std 选项 __cplusplus 值
Zc:__cplusplus /std:c++14(默认值) 201402L
Zc:__cplusplus /std:c++17 201703L
Zc:__cplusplus /std:c++20 202002L
Zc:__cplusplus /std:c++latest 当前最新日期,目前是202002L
Zc:__cplusplus-(已禁用) 任何值 199711L
未指定 任何值 199711L

表中的/std 选项就是上一节的C++语言标准属性。

可见,如果没有添加/Zc:__cplusplus__cplusplus宏的值始终都是199711L,启用的c++17标准也是不完整的。微软这么操作的理由是:有很多老代码写得不规范(不符合语言标准),之前版本的编译器(由于对语言标准的遵守不严格)能编译通过,我们希望使用新编译器时它们的改动也尽可能小。

于是,本来支持严格的标准C++语法的编译器的默认状态仍和原来一样,__cplusplus宏的值始终是199711L;直到开发者在编译器的命令行中加入/Zc:__cplusplus,它才真正变成实际使用语言标准的值。

其实多数情况下,__cplusplus宏的值对代码编译影响不大。但是很多高水平开源库使用了新语法,恰恰需要__cplusplus宏的值符合语言标准(/std 选项)才能编译通过,这是对开源开发者很不友好的。

P.S. 官方的愿景是,有朝一日仅需要设定/std 选项__cplusplus宏的值就随之改变,不需要额外添加/Zc:__cplusplus

解决方法

属性页---C/C++---命令行---其他选项中添加:/Zc:__cplusplus。重新编译,即可。

扩展阅读

/Zc-cplusplus的微软官方说明
C++语言标准切换选项
官方:终于能正确设定__cplusplus值了

用/std选项确定c/c++语言标准
强制符合语法标准选项/permissive-

一点认识:MSVC的C/C++编译器默认情况下实现了当前标准和未来一些标准中的语法。当指定语言标准为默认的/std:c++14时,大部分新标准的语法将被禁用,但仍有一部分在引入/std选项之前就实现的新语法标准可用。

但指定/std:c++xx(xx>14)时,新实现的c++xx以后的语法将不可用。

相关推荐
UQWRJ22 分钟前
菜鸟教程R语言一二章阅读笔记
开发语言·笔记·r语言
岁忧2 小时前
macOS配置 GO语言环境
开发语言·macos·golang
朝朝又沐沐3 小时前
算法竞赛阶段二-数据结构(36)数据结构双向链表模拟实现
开发语言·数据结构·c++·算法·链表
魔尔助理顾问3 小时前
系统整理Python的循环语句和常用方法
开发语言·后端·python
Ares-Wang3 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
逝雪Yuki4 小时前
Leetcode——287. 寻找重复数
c++·leetcode·二分查找·双指针·环形链表
遇见尚硅谷4 小时前
C语言:*p++与p++有何区别
c语言·开发语言·笔记·学习·算法
SkyrimCitadelValinor4 小时前
c#中让图片显示清晰
开发语言·c#
艾莉丝努力练剑5 小时前
【数据结构与算法】数据结构初阶:详解排序(二)——交换排序中的快速排序
c语言·开发语言·数据结构·学习·算法·链表·排序算法
狐小粟同学5 小时前
JavaEE--3.多线程
java·开发语言·java-ee