2016-06-02 13 views
15

GCC v6.1 (das Ergebnis ist das gleiche mit v5.1) erfolgreich kompiliert den Code unten mit Fahnen -std=c++11 -Wall -Wextra -Wpedantic, sondern produziert diese Warnung:Warum ist die Kompilierung mit C++ 11 erfolgreich, obwohl die C++ 14-Funktion verwendet wird?

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

Der Code:

#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 0,8 erzeugt eine ähnliche Warnung:

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

Wenn dies ein Feature nur in C++ 14, warum es mit C++ 11-Flag kompiliert nur fein und I c ein Ausführen der ausführbaren Datei? Sollte es nicht ein fataler Fehler sein?

+3

Verwenden Sie '-pedantic-errors' für einen Fehler –

+0

@PiotrSkotnicki Sicher, aber wie kann das Programm erstellt und ohne die erforderliche Funktion ausgeführt werden? – DBedrenko

+1

Warum denkst du, dass es ohne die erforderliche Funktion läuft? –

Antwort

12

Der C++ - Standard hat nicht das Konzept eines "fatalen Compiler-Fehler". Programme sind entweder schlecht ausgebildet mit einer erforderlichen Diagnose oder schlecht ausgebildet, ohne dass eine Diagnose erforderlich oder wohlgeformt ist.

In C++ besteht die einzige Anforderung, die der Standard an eine schlecht geformte Programmdiagnose stellt, darin, eine Diagnose anzuzeigen. Der Inhalt dieser Diagnose ist nicht definiert. Was sonst noch neben dieser Diagnose passiert, ist nicht definiert.

Viele Compiler implementieren Erweiterungen des C++ - Standards, die sie kompilieren sollen, um ansonsten schlecht geformte Programme zu kompilieren und eine ausführbare ausführbare Datei zu erzeugen. Wenn sie einem Standard entsprechen, müssen sie lediglich eine Warnmeldung ausgeben (die den Diagnoseanforderungen der C++ - Norm (en) genügt).

In diesem Fall wird eine Warnmeldung ausgegeben, dass Sie eine C++ 14-Funktion verwendet haben. Es hat nun erfolgreich gemacht, was der C++ 11-Standard mit Ihrem schlecht geformten Programm erfordert. Es erzeugt auch eine ausführbare Datei, die das tut, was Ihr Programm tun würde, wenn diese Funktion aus dem C++ 14-Standard verwendet würde: es ist frei, dies zu tun, da der Standard an diesem Punkt keine Einschränkungen für das Programm vorsieht, sobald es ein ist schlecht ausgebildetes C++ 11-Programm.

Wenn Sie diese Option nicht wünschen, haben Compiler oft ein warnings-as-errors Flag und verschiedene strict und pedantic Flags, die Erweiterungen zu dem Standard blockieren, den sie verwenden. Dann unterdrückt der Fehler die Generierung der ausführbaren Datei und Sie werden nicht länger verwirrt sein.

gcc nimmt standardmäßig an, dass Sie den bereitgestellten Code tatsächlich in etwas kompilieren möchten und nicht als Standard-Enforcer fungieren. Er generiert nur dann Fehler, wenn er keine vernünftige Möglichkeit hat, Ihren Code als Programm zu interpretieren, das Ihren Absichten entspricht . Es bietet Flags, um es in einen strikten und pedantischen Modus zu versetzen.


Amüsant, genügt ein einzelnes Leerzeichen Ausdruck der Anforderung eines Diagnose anzuzeigen.Der C++ - Standard kann auf pathologische Weise gelesen werden, um eine schlechte Implementierungsqualität in Ihrem Compiler zu erzeugen: Die Erstellung eines feindlichen Compiler-sicheren Standards ist den Aufwand nicht wert.

+0

Vielen Dank und alle, die auf meine Frage geantwortet haben. Was für eine ausgezeichnete Antwort! Ich habe heute viel über Compiler gelernt. Eine gute Sache hinzuzufügen (was die praktische Lösung für meine Frage ist), ist die Verwendung des Flags '-pendatic-errors' (in Kombination mit '-std = C++ 11 -pedantic'), was dazu führt, dass der Compiler ein wirft Fehler, wenn eine C++ 14-Funktion verwendet wird. – DBedrenko

+2

"Es erzeugt auch eine ausführbare Datei, die das tut, was Ihr Programm tun würde, wenn es unter dem C++ 14-Standard kompiliert wäre" - nur in Bezug auf dieses spezielle Feature: Es gibt möglicherweise noch andere Teile des Programms, die erfolgreich mit C kompiliert wurden ++ 11 Regeln, die in C++ 14 anders wären. –

2

Nichts "sollte ein fataler Fehler sein". Wenn der Compiler eine Nachricht schreibt, die Ihnen sagt, was passiert ist, hat er seine Verpflichtungen erfüllt.

Sie können jetzt eine vollständig informierte Entscheidung treffen, ob Sie den Code als schwerwiegenden Fehler behandeln und den Code ändern möchten. oder es als C++ 14 zu behandeln und damit zu gehen.

Sie können den Schalter -Werror verwenden (ändert das Wort "Warnung" in "Fehler" in der Nachricht), wenn Sie denken, dass es helfen würde.

+0

Danke für die Antwort. Wenn das Programm ohne dieses Feature ausgeführt werden kann, dann ist die Auswirkung meiner Frage, was ist das Verhalten von 'FooMap', wenn es mit C++ 11 kompiliert wird? Der "filly informed" Teil in Ihrer Antwort ist, was eine sehr nützliche Antwort wäre. – DBedrenko

+1

@SpaghettiCat Es wird nicht "ohne diese Funktion ausgeführt". Das Feature wird vollständig kompiliert, als ob Sie "-std = C++ 14" verwenden würden. Der einzige Unterschied besteht darin, dass Sie eine Warnung erhalten. – HolyBlackCat

+0

@HolyBlackCat Oh richtig .... so erzwingt der Compiler die Verwendung von '-std = C++ 14', wenn es Code sieht, der nur C++ 14 ist? Ich war mir dieses Verhaltens nicht bewusst ... – DBedrenko

Verwandte Themen