Неправильно ли gcc не диагностирует сужающиеся преобразования в не типовых аргументах шаблона?
Следующая программа компилируется без ошибок или предупреждений с помощью gcc 4.8.1,-Wall -std=c++11
:
template<unsigned N>
struct A{};
int main(){
A<1-2> a;
(void)a;
return 0;
}
clang 3.3 с теми же параметрами выдает эту ошибку:
ошибка: нетипизированный аргумент шаблона имеет значение -1, которое нельзя сузить до типа unsigned int [-WC++11-сужение]
Что касается этого вопроса, то похоже, что нынешняя политика gcc состоит в том, чтобы просто предупреждать о сужающихся конверсиях, когда стандарт указывает на ошибки, и где clang выдает указанные ошибки. Но в этом случае GCC даже не дает предупреждение.
Ни один из примеров сужающих ошибок преобразования, приведенных в стандарте в п. 8.5.4/7 (воспроизведенных в этом вопросе), не охватывает случай сужающего преобразования аргумента шаблона нетипичного типа, но в п. 14.3.2/5 Стандарт гласит:
Для нетипового шаблона-параметра целочисленного или перечислимого типа применяются преобразования, разрешенные в преобразованном константном выражении (5.19).
И в п. 5.19/3 говорится:
Преобразованное константное выражение типа T является литеральным константным выражением, неявно преобразуемым в тип T, где неявное преобразование (если оно есть) разрешено в литеральном константном выражении, а неявная последовательность преобразования содержит только определенные пользователем преобразования, lvalue-to-r-значения преобразований (4.1), интегральные преобразования (4.5) и интегральные преобразования (4.7), кроме сужающих преобразований (8.5.4)
(мой акцент).
Мне кажется, это означает, что даже по своему критерию gcc виноват в том, что не диагностирует сужающееся преобразование в этом случае. Я правильно понял? Есть ли основанный на стандартах контраргумент?
Я задаю вопрос с большим чувством, что просто любопытство. В рекурсивной настройке TMP диагностика ошибок clang в этом случае будет точно определять ошибку, при которой аргумент шаблона без знака без типа пропускается через 0, тогда как все, что вы получаете от gcc, это "максимальная глубина экземпляра шаблона превышена".
1 ответ
GCC не такой педантичный, как Clang, однако он все еще может обнаруживать такие ошибки:
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
на самом деле не включает все возможные проверки. Прочитайте эту страницу для большего количества примеров: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
я использую gcc.EXE (GCC) 4.8.0 20130203 (experimental)