2013-07-09 4 views
11

Poniższy program kompiluje bez błędów lub ostrzeżenia z gcc 4.8.1, -Wall -std=c++11:Czy gcc jest błędne, nie diagnozując zwężających się konwersji w argumentach szablonu innego typu?

template<unsigned N> 
struct A{}; 

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

brzękiem 3,3 z tymi samymi opcjami daje ten błąd:

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

Zgodnie this question, wygląda jak w obecnej polityce gcc, aby podać ostrzeżenia o zwężeniu konwersji, gdzie Standard wskazuje błędy i gdzie klang podaje wskazane błędy. Ale w tym przypadku gcc nawet nie daje ostrzeżenia.

Żaden z przykładów zwężenie błędów konwersji, które zostały podane przez Standardu w § 8.5.4/7 (reprodukowane w that question) obejmuje przypadek konwersji zwężenia typu non-szablonu argumentu, ale w § 14.3.2/5 standard mówi:

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

i § 5.19/3 mówi:

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)

(podkreślenie moje).

To wydaje mi się oznaczać, że nawet na podstawie własnego miernika gcc ponosi winę, nie diagnozując w tym przypadku konwersji zwężenia . Czy to czytam dobrze? Czy istnieje kontrofalator oparty na standardzie ?

Zadaję pytanie z większym poczuciem tej zwykłej ciekawości. W rekurencyjnym ustawieniu TMP , diagnostyka błędu klangowego w tym przypadku zidentyfikuje błąd , w którym niepodpisany argument szablonu typu nie mieści się w przedziale , natomiast wszystko, co dostajesz z gcc, to "przekroczenie maksymalnej głębokości instancji szablonu".

+1

standardowego nigdy „wzywa do błędów” lub ostrzeżeń - norma wymaga jedynie implementację wydać diagnostyczny * *. To, czy taka diagnoza przybiera postać błędu kompilatora, czy ostrzeżenia, lub czegoś zupełnie innego od nich obu, wykracza poza zakres normy. – Casey

+0

@ Casey. Rozumiem, ale kwestionuję brak * jakiegokolwiek * diagnostyki; brak niczego oprócz sukcesu. –

+0

@ Casey. Nie, przepraszam. Powiedziałem "wymagane błędy" i nie powinno. –

Odpowiedz

2

GCC nie jest tak pedantyczne jak Clang, jednak nadal może wykryć tych rodzaju błędów:

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 faktycznie nie włączyć wszystkie możliwe kontrole. Przeczytaj tę stronę po więcej przykładów: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

Używam gcc.EXE (GCC) 4.8.0 20130203 (experimental)

+3

To jest przydatny punkt (+1), ale nie sądzę, że jest to odpowiedź. § 5.19/3 (cytowany) * pozwala * przekształcone wyrażenie stałe na być * niejawnie przekonwertowane * na typ docelowy, ale nadal wyraźnie zakazuje zawężania konwersji. '-Wsign-conversion' podaje użyteczne informacje o konwersji, na którą pozwala standard.Tak więc nie jest aktywowany nawet przez "-pedantic", ale nawet przy "-pedantic" nie ma diagnostyki zwężającego się przekształcenia, które Standard zabrania. To ostrzeżenie GCC jest również wspólne dla C i jest znacznie starsze niż zakaz zawężania konwersji w C++ 11. –

+2

Próbowałem również "-pedantic'' i byłem rozczarowany. Wygląda to na błąd kompilatora. –

+2

Zgłosiłem to jako błąd, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57891. –

Powiązane problemy