gpt4 book ai didi

c++ - 如何以编程方式获取VS2017 Update 8.2中/permissive-设置的所有编译器标志

转载 作者:行者123 更新时间:2023-12-02 10:58:18 25 4
gpt4 key购买 nike

如何以编程方式获取由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 |重载并将其引入全局 namespace 。上面的 |表达式中的操作数仅包含非相关名称。因此,此表达式实际上不应受到 operator |的存在的影响,因为要决定使用哪个运算符函数应该在 std::basic_stringbuf::seekoff()定义中首次遇到该表达式的点上进行。但是,据我所知,Visual C++编译器实际上只是将模板函数实例放在翻译单元的末尾。基于 [temp.point]/8本身允许这样做。但是,Visual C++过去也将所有名称查找延迟到模板实例化时间 documented non-standard behavior上。没有 /permissive-开关,编译器仍将执行此非标准名称查找作为兼容性功能。然后它将找到并尝试使用比内置运算符更好的 operator |,因为这两个操作数都是枚举类型,并且需要 integral promotion。使用 /permissive-,编译器将执行正确的两阶段名称查找,并正确地决定使用内置的 |运算符。

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

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

关于c++ - 如何以编程方式获取VS2017 Update 8.2中/permissive-设置的所有编译器标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53499220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com