簡體   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