2013-07-09 42 views
11

Das folgende Programm kompiliert ohne Fehler oder Warnung mit gcc 4.8.1, -Wall -std=c++11:Ist gcc falsch, um die Conversions in Nicht-Template-Argumenten einzuschränken?

template<unsigned N> 
struct A{}; 

int main(){ 
    A<1-2> a; 
    (void)a; 
    return 0; 
} 

Klirren 3.3 mit den gleichen Optionen gibt diesen Fehler:

error: non-type template argument evaluates to -1, which cannot be narrowed to type 'unsigned int' [-Wc++11-narrowing]

Per this question, sieht es Wie die aktuelle Richtlinie von GCC, nur um Warnungen für das Einschränken von Konvertierungen zu geben, wobei der Standard Fehler anzeigt, und wo Clang die angegebenen Fehler gibt. Aber in diesem Fall gibt gcc nicht einmal eine Warnung aus.

Keines der Beispiele von Umwandlungsfehlern, die schmäler 8.5.4/7 (wiedergegeben in that question) durch die Standard- bei § gegeben sind deckt den Fall einer Verengung Umwandlung eines nicht-Typ Template-Argument, aber § 14.3.2/5 der Norm sagt:

For a non-type template-parameter of integral or enumeration type, conversions permitted in a con- verted constant expression (5.19) are applied.

und 5,19/§3 sagt:

A converted constant expression of type T is a literal constant expression, implicitly converted to type T, where the implicit conversion (if any) is permitted in a literal constant expression and the implicit conversion sequence contains only user-defined conversions, lvalue-to-rvalue conversions (4.1), integral promotions (4.5), and integral conversions (4.7) other than narrowing conversions (8.5.4)

(Hervorhebung von mir).

Dies scheint mir zu bedeuten, dass selbst durch seinen eigenen Maßstab gcc ist in keiner Weise diagnostizieren eine Verengung Umwandlung in diesem Fall. Lies ich das richtig? Gibt es ein Standard-basiertes Gegenargument?

Ich stelle die Frage mit mehr Gefühl, dass nur Neugier. In einer rekursiven TMP-Einstellung wird die Fehlerdiagnose von clang in diesem Fall einen Fehler feststellen, bei dem ein vorzeichenloses Nicht-Typ-Template-Argument durch 0 fällt, während alles, was Sie von gcc erhalten, "maximale Template-Instanziierungstiefe überschritten" ist.

+1

Der Standard mit nie „Anrufe für Fehler“ oder für Warnungen - der Standard nur eine Implementierung erfordert * eine * Diagnose auszustellen. Ob eine solche Diagnose die Form eines Compilerfehlers oder einer Warnung oder etwas völlig anderes als die beiden annimmt, liegt außerhalb des Anwendungsbereichs des Standards. – Casey

+0

@Casey. Ich verstehe, aber ich stelle die Abwesenheit von irgendwelchen Diagnosen in Frage. die Abwesenheit von allem außer Erfolg. –

+0

@Casey. Nein, meine Entschuldigung. Ich sagte "die erforderlichen Fehler" und sollte nicht haben. –

Antwort

2

GCC ist nicht so pedantisch wie Clang, aber es immer noch diese Art von Fehler erkennen können:

gcc -Wsign-conversion 1.cpp 
1.cpp: In function 'int main()': 
1.cpp:5:10: warning: negative integer implicitly converted to unsigned type [-Wsign-conversion] 
    A<1-2> a; 
     ^

-Wall eigentlich nicht auf alle möglichen Kontrollen zu machen. Lesen Sie diese Seite, um weitere Beispiele: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

Ich gcc.EXE (GCC) 4.8.0 20130203 (experimental)

+3

Das ist ein nützlicher Punkt (+1), aber ich denke nicht, dass es eine Antwort ist. § 5.19/3 (quotiert) * erlaubt * den konvertierten Konstantenausdruck nach * implizit in Zieltyp * umwandeln, verbietet aber immer noch ausdrücklich eine engere Umrechnung. '-Wsign-conversion' gibt eine nützliche Diagnose einer Konvertierung, die der Standard zulässt.Somit wird selbst durch "-pedantische" nicht aktiviert, aber selbst mit "-pedantisch" gibt es keine Diagnose der einschränkenden Umwandlung, die der Standard verbietet. Diese GCC-Warnung ist auch in C üblich und ist viel älter als das Verbot einschränkender Conversions in C++ 11. –

+2

Ich habe auch '' pedantic'' versucht und war enttäuscht. Das sieht für mich wie ein Compilerfehler aus. –

+2

Ich habe es als Fehler gemeldet, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57891. –