繁体   English   中英

如何以编程方式获取VS2017 Update8.2中/ permissve-设置的所有编译器标志

[英]How to get programatically all the compiler flags set by /permissve- in VS2017 Update8.2

如何以编程方式获取由Visual Studio 2017编译器启用的选项标志/ permissive-

根据Microsoft文档/ permissive-flag设置/ Zc编译器选项以实现严格一致性

现在,下面的代码在仅启用/ permissive-编译器标志的Visual Studio 2017 Update8.2上进行编译,并且在未打开/ permissive-标志的情况下失败(在Vs2017 Update 8.2上)

#include <sstream>

namespace ABC {

template <typename T>

bool operator|(T v1, T v2) {
}}

std::stringstream ss_; //commenting this removes the error

using namespace ABC;

int main() {
return 0;
}

我想知道/ Zc的哪个编译器标志已修复此问题

如果没有/permissive-则会出现此问题,因为编译器将不会对模板执行正确的两阶段名称查找。

在sstream的270行中,您将找到:

            …
            constexpr auto _Both = ios_base::in | ios_base::out;
            …

作为std::basic_stringbuf::seekoff()定义的一部分,它是一个虚拟成员函数。 std::basic_stringstream<char>包含一个成员,该成员是std::basic_stringbuf实例,其构造需要定义虚拟成员函数。

包括<sstream> ,您可以定义一个通用operator |并将其引入全局名称空间operator | 超载。 |的操作数 上面的表达式仅包含非相关名称。 因此,该表达式实际上不应受到operator | 因为决定使用哪个运算符应该在std::basic_stringbuf::seekoff()的定义中首先遇到表达式的地方发生。 但是,据我所知,Visual C ++编译器实际上只是将模板函数实例放在翻译单元的末尾。 本身基于[temp.point] / 8是允许的。 但是,Visual C ++过去也将所有名称查找延迟到模板实例化时间,这已记录为非标准行为 没有/permissive-开关,编译器仍将执行此非标准名称查找作为兼容性功能。 然后它将找到并尝试使用您的operator | 这是比内置运算符更好的匹配,因为两个操作数都是枚举类型,并且需要整数提升 使用/permissive- ,编译器将执行正确的两阶段名称查找,并正确决定使用内置| 运算符。

有一个/Zc:twoPhase-标志对这个不规范的行为明确启用时/permissive-生效。 因此,您只需打开/permissive-/Zc:twoPhase-并观察到这会像预期的那样带回错误,就可以验证问题实际上是由非标准名称查找引起的。

除此之外,请注意您的operator | 不会返回值,因此,如果最终在任何地方实际使用此运算符,最终将导致调用未定义的行为…;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM