При использовании перечисления с областью действия в контексте varargs он определяется как его базовый тип, как указано в «Can I use enum class values as arguments to varargs functions?». Как я понимаю, это единственное обстоятельство, в котором скопированное перечисление будет преобразовано неявно, например неперечисленное перечисление.Правильно ли GCC предупреждать о несоответствии строки формата с областью перечисления?
Рассмотрим эту программу:
enum Foo : char { F };
enum class Bar : char { B };
#include <cstdio>
int main()
{
return !std::printf("%c\n", Foo::F)
+ !std::printf("%c\n", Bar::B);
}
Компилятор (g++
версия 6.3.0) счастлив с первым тиражи, в Foo
, но жалуется, когда я прохожу Bar
:
0.cpp: In function ‘int main()’:
0.cpp:10:34: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘Bar’ [-Wformat=]
+ !printf("%c\n", Bar::B);
^
g++
версия 4.8.2 не жаловалась на это, но g++
6.3.0 делает (и именно поэтому это теперь касается меня). Обе версии жалуются на первую распечатку при наличии существенного несоответствия, например, с использованием %f
или %s
, или если я изменю Foo
, чтобы использовать базовый тип long
; поэтому я включаю -Wformat
.
Я понимаю, что предупреждения не являются проблемой соответствия стандартам, и я знаю, как изменить свой код для их решения (например, используя функции в ответах на How can I output the value of an enum class in C++11?), но я также считаю, что предупреждения бесполезны, если они производят ложные позитивы. Существует ли какой-либо потенциал для фактического вреда при передаче области с перечнем в форматированную функцию ввода-вывода, когда базовый тип перечисления соответствует соответствующей спецификации преобразования в строке формата?
GCC версия 4.8, вероятно, не жаловалась, потому что у нее не было полной реализации C++ 11, а расширенные перечисления были введены в C++ 11. –
См. Принятый ответ из связанного с вами вопроса: значения неперечисленного числа перечислены как целочисленные, но ограниченные перечисления (элементы класса enum) - нет. – cpplearner
@cpplearner Даже если я изменю 'Bar' на' enum class: int', он жалуется на несоответствие, так что это только часть ответа. –