简体   繁体   English

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

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

How to get programatically, options enabled by Visual Studio 2017 compiler flag /permissive- 如何以编程方式获取由Visual Studio 2017编译器启用的选项标志/ permissive-

As per Microsoft Documentation /permissive- flag sets the /Zc compiler options for strict conformance 根据Microsoft文档/ permissive-flag设置/ Zc编译器选项以实现严格一致性

Now the below code gets compiled on Visual Studio 2017 Update8.2 with only /permissive- compiler flag on , and fails when /permissive- flag is not turned on (on Vs2017 Update 8.2) 现在,下面的代码在仅启用/ 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;
}

I want to know which compiler flag of /Zc fixed this 我想知道/ Zc的哪个编译器标志已修复此问题

The problem occurs without /permissive- because the compiler will not perform proper two-phase name lookup for templates. 如果没有/permissive-则会出现此问题,因为编译器将不会对模板执行正确的两阶段名称查找。

In sstream, line 270 you'll find: 在sstream的270行中,您将找到:

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

as part of the definition of std::basic_stringbuf::seekoff() which is a virtual member function. 作为std::basic_stringbuf::seekoff()定义的一部分,它是一个虚拟成员函数。 std::basic_stringstream<char> contains a member that is an std::basic_stringbuf instance, the construction of which requires the definition of the virtual member functions. std::basic_stringstream<char>包含一个成员,该成员是std::basic_stringbuf实例,其构造需要定义虚拟成员函数。

After including <sstream> , you define and introduce into the global namespace a generic operator | 包括<sstream> ,您可以定义一个通用operator |并将其引入全局名称空间operator | overload. 超载。 The operands in the | |的操作数 expression above contain only non-dependent names. 上面的表达式仅包含非相关名称。 Therefore, this expression should actually not be affected by the presence of your operator | 因此,该表达式实际上不应受到operator | because the decision which operator function to use should happen at the point where the expression is first encountered in the definition of std::basic_stringbuf::seekoff() . 因为决定使用哪个运算符应该在std::basic_stringbuf::seekoff()的定义中首先遇到表达式的地方发生。 However, (as far as my understanding goes) the Visual C++ compiler will effectively just put template function instances at the end of the translation unit. 但是,据我所知,Visual C ++编译器实际上只是将模板函数实例放在翻译单元的末尾。 This in itself is allowed based on [temp.point]/8 . 本身基于[temp.point] / 8是允许的。 However, Visual C++ used to also delay all name lookup to template instantiation time which is documented non-standard behavior . 但是,Visual C ++过去也将所有名称查找延迟到模板实例化时间,这已记录为非标准行为 Without the /permissive- switch, the compiler will still perform this non-standard name lookup as a compatibility feature. 没有/permissive-开关,编译器仍将执行此非标准名称查找作为兼容性功能。 It will then find and try to use your operator | 然后它将找到并尝试使用您的operator | which is a better match than the built-in operator because both operands are of enumeration type and would require an integral promotion . 这是比内置运算符更好的匹配,因为两个操作数都是枚举类型,并且需要整数提升 With /permissive- , the compiler will perform proper two-phase name lookup and correctly decide to use the built-in | 使用/permissive- ,编译器将执行正确的两阶段名称查找,并正确决定使用内置| operator instead. 运算符。

There is a /Zc:twoPhase- flag to explicitly turn on this non-standard behavior when /permissive- is in effect. 有一个/Zc:twoPhase-标志对这个不规范的行为明确启用时/permissive-生效。 Thus, you can verify that the problem actually is caused by non-standard name lookup simply by switching on /permissive- and /Zc:twoPhase- and observing that this brings back the error as one would expect… 因此,您只需打开/permissive-/Zc:twoPhase-并观察到这会像预期的那样带回错误,就可以验证问题实际上是由非标准名称查找引起的。

Apart from that, note that your operator | 除此之外,请注意您的operator | does not return a value, so if you end up actually using this operator function anywhere, you'll end up invoking undefined behavior… ;) 不会返回值,因此,如果最终在任何地方实际使用此运算符,最终将导致调用未定义的行为…;)

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

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