2013-07-09 29 views
11

Il seguente programma viene compilato senza errori o avvertimento con gcc 4.8.1, -Wall -std=c++11:gcc non è in grado di diagnosticare il restringimento delle conversioni negli argomenti modello non di tipo?

template<unsigned N> 
struct A{}; 

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

clang 3.3 con le stesse opzioni dà questo errore:

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

Come per this question, sembra come la presente politica di gcc solo per dare avvertimenti per il restringimento delle conversioni in cui lo standard indica errori e dove clang dà gli errori indicati. Ma in questo caso gcc non dà nemmeno un avvertimento.

Nessuno degli esempi di restringimento errori di conversione che vengono dati dal standard al § 8.5.4/7 (riprodotto in that question) copre il caso di una conversione restringimento di un argomento di template non tipo, ma a § 14.3.2/5 standard dice:

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

e § 5.19/3 dice:

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)

(il corsivo è mio).

Questo mi sembra significare che anche con il proprio metro di valutazione gcc è in errore non diagnosticare affatto una conversione di restringimento in questo caso. Leggo bene? C'è un controargomento basato sullo standard ?

Sto facendo la domanda con più sentimento che semplice curiosità. In un ambiente TMP ricorsiva , l'errore di clang diagnostico in questo caso sarà individuare un bug in cui un non-modello tipo di argomento unsigned cade attraverso 0, mentre tutti si ottiene da gcc è "modello di profondità massima di un'istanza superato".

+1

Lo standard mai "inviti a presentare errori" o per avvisi - lo standard richiede solo un'implementazione di emettere una diagnosi * *. Se tale diagnostica prende la forma di un errore del compilatore o di un avvertimento o qualcosa di completamente diverso da entrambi, non rientra nell'ambito dello standard. – Casey

+0

@Casey. Capisco, ma sto mettendo in dubbio l'assenza di * qualsiasi * diagnosi; l'assenza di altro che il successo. –

+0

@Casey. No, mi scuso. Ho detto "gli errori richiesti" e non avrei dovuto. –

risposta

2

GCC non è così pedanti come Clang, tuttavia, può ancora rilevare questo tipo di errori:

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 in realtà non girare su tutti i possibili controlli. Leggere questa pagina per ulteriori esempi: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

sto usando gcc.EXE (GCC) 4.8.0 20130203 (experimental)

+3

Questo è un punto utile (+1), ma non penso che sia una risposta. § 5.19/3 (quotato) * consente * l'espressione costante convertita a * convertita * implicitamente * al tipo di destinazione, ma proibisce espressamente una conversione restringente. '-Wsign-conversion' fornisce una diagnostica utile di una conversione consentita dallo standard.Quindi non è attivato nemmeno da '-pedantic', ma anche con' -pedantic' non esiste una diagnostica della conversione di restringimento che la norma proibisce. Questo avviso GCC è anche comune a C ed è molto più vecchio del divieto di restringere le conversioni in C++ 11. –

+2

Ho provato anche '' -pedantic'' e sono rimasto deluso. Questo mi sembra un bug del compilatore. –

+2

L'ho segnalato come un bug, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57891. –