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.
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
@Casey. Ich verstehe, aber ich stelle die Abwesenheit von irgendwelchen Diagnosen in Frage. die Abwesenheit von allem außer Erfolg. –
@Casey. Nein, meine Entschuldigung. Ich sagte "die erforderlichen Fehler" und sollte nicht haben. –