簡體   English   中英

盡管使用C ++ 14功能,為什么使用C ++ 11進行編譯仍然是成功的?

[英]Why compiling with C++11 is successful despite using C++14 feature?

GCC v6.1(結果與v5.1相同)使用flags -std=c++11 -Wall -Wextra -Wpedantic成功編譯了下面的代碼,但產生了這個警告:

variable templates only available with -std=c++14 or -std=gnu++14

代碼:

#include <iostream>

template <typename T>
struct ParamMetadata {
        T min;
        T max;
};

template <class T1, class T2>
class FooMap {};

template <typename T>
// WARNING PRODUCED ON THIS LINE
extern FooMap<int, ParamMetadata<T> > metadataHashmap;

int main() {
        return 0;
}

Clang v3.8產生了類似的警告:

variable templates are a C++14 extension [-Wc++14-extensions]

如果這是僅在C ++ 14中可用的功能,為什么用C ++ 11標記編譯就好了,我可以運行可執行文件? 這不應該是一個致命的錯誤嗎?

C ++標准沒有“致命的編譯器錯誤”的概念。 程序要么形成錯誤,要么需要診斷,要么形成不良,不需要診斷或形式良好。

在C ++中,標准對錯誤的程序診斷的唯一要求是顯示診斷1 未定義該診斷的內容。 除了診斷之外還會發生什么其他事情。

許多編譯器實現了C ++標准的擴展,他們被告知要編譯它們,否則就會產生不正確的程序並產生可運行的可執行文件。 如果它們符合標准,他們唯一必須做的就是打印一條警告信息(滿足C ++標准的診斷要求)。

在這種情況下,它正在打印您使用C ++ 14功能的警告消息。 它現在已成功完成了C ++ 11標准所需的錯誤程序。 它還生成一個可執行程序,它可以執行程序在使用C ++ 14標准的功能時所執行的操作:它可以自由執行,因為此時標准對程序執行的操作沒有任何限制。格式不正確的C ++ 11程序。

如果您不想要此選項,編譯器通常會有一個warnings-as-errors標志,以及各種strictpedantic標志,這些標志會阻止他們使用的標准的擴展。 然后該錯誤將抑制可執行文件的生成,您將不再感到困惑。

默認情況下,gcc假定您實際上希望將提供的代碼編譯成某些內容,而不是作為標准實施者,並且只有在沒有合理的方法將您的代碼解釋為可能符合您的意圖的程序時才會生成錯誤。 它提供標志以將其切換到嚴格和迂腐模式。


1有趣的是,打印出單個空格字符可滿足顯示診斷的要求。 可以用病理方式讀取C ++標准,以便在編譯器中生成低質量的實現:生成惡意的編譯器證明標准是不值得的。

沒有什么“應該是一個致命的錯誤”。 如果編譯器寫了一條消息,告訴你發生了什么,它就履行了它的義務。

您現在可以自由決定是否將代碼視為致命錯誤並更改代碼; 或者把它當作C ++ 14來對待並隨之而去。

您可以使用開關-Werror (如果您覺得它-Werror可以在-Werror “警告”更改為“錯誤”)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM