Bei der Erstellung eines MCVE für dieses Problem, über das ich gestolpert bin, habe ich die folgende Diskrepanz zwischen Compilern gefunden:
Betrachten Sie den folgenden Code:
%Vor%Dieser Code wird in Clang 3.8.0 kompiliert, schlägt aber in GCC 6.1.0 mit:
fehl %Vor% Das Auskommentieren von // 2
und das Auskommentieren von // 1
funktioniert auf beiden Compilern.
Interessanterweise wird das Verschieben der f
-Definition anstelle von // 1
kompiliert, löst jedoch eine Warnung bei // 2
aus:
Welcher Compiler ist richtig?
Das Ersetzen der constexpr
Funktionen durch inline
Funktionen behält das exakt gleiche Problem bei (es ist okay mit der globalen Deklaration 1, aber nicht mit der Funktion-Scope Deklaration 2.) Da constexpr
impliziert inline
das scheint wie die Ursache.
In diesem Fall beschwert sich der GCC mit der Erklärung 2:
%Code%
und warning: 'inline' specifier invalid for function 'f' declared out of global scope
.
Es kann nicht verlinkt werden (" warning: inline function 'int f()' used but never defined
").
Es sieht also so aus, als ob es beim Inlining aufgibt, einen Anruf tätigt, aber keinen Code für undefined reference to 'f()'
ausgibt, weil alle Verwendungen inline sind (?), so dass die Verbindung fehlschlägt.
und Clang beschwert sich:
f()
Da error: inline declaration of 'f' not allowed in block scope
für constexpr
steht, scheint diese Regel, dass Inline-Deklarationen im Blockbereich nicht erlaubt sind, auch auf inline
zutreffen, und daher ist GCC korrekt. Aber der Standard scheint nicht herauszukommen und dies zu sagen. In dem von mir untersuchten Entwurf ist die Regel über constexpr
in §7.1.2 [dcl.fct.spec], Teil 3: "Der Inline-Spezifizierer darf nicht in einer Block-Scope-Funktionsdeklaration erscheinen", aber nichts Ähnliches erscheint über inline
.
Tags und Links c++ language-lawyer constexpr function-declaration compiler-bug