Почему C++ выдает предупреждения о перечислениях с отрицательными значениями?

Мой текущий код выглядит следующим образом:

enum Enum1 : signed __int8
{
    Value1 = 1 ,
    Value2 = 2 ,
    Value3 = -3  // C4341
} ;

В сведениях об ошибке указано:
"предупреждение C4341: "Value3": значение со знаком выходит за пределы допустимого диапазона для константы перечисления"

MSDN заявляет, что это предупреждение возникает только при использовании значений вне диапазона int:
(> 2^31) ИЛИ (‹ 1 - 2^31)

Почему он говорит мне, что мои отрицательные значения недействительны? Это всего лишь предупреждение, но Google говорит мне, что это предупреждение указывает на то, что эти значения перечисления будут неопределенными, что нарушит мою программу.


person Giffyguy    schedule 04.11.2010    source источник
comment
Будет ли он жаловаться, если вы определите его в шестнадцатеричном формате? (подписано __int8)-3 == hex 0xFD == dec 253 (если ваша машина в любом случае является дополнением до двух...)   -  person JimR    schedule 04.11.2010
comment
@JimR выдает ошибку, утверждая, что 0xFD — это значение без знака, присваиваемое переменной со знаком.   -  person Giffyguy    schedule 04.11.2010
comment
@Giffyguy: попробуйте char вместо __int8. Мне любопытно, получите ли вы предупреждение (они должны быть одинаковыми в VS).   -  person Jason Iverson    schedule 04.11.2010
comment
@Jason char (и подписанный char) дают идентичные результаты: C4341 для -3 и C4369 для 0xFD   -  person Giffyguy    schedule 04.11.2010
comment
@Giffyguy: Ну, я не получаю предупреждения в gcc4.4 и выше, поэтому я в растерянности. Может быть, Microsoft испортила реализацию C++0x?   -  person Jason Iverson    schedule 04.11.2010
comment
@GiffyGuy Тогда должно быть VS 2010. Я не видел этого с VS2008 или ранее.   -  person JimR    schedule 04.11.2010
comment
@JimR: Это правильно. Я использую VS2010.   -  person Giffyguy    schedule 04.11.2010


Ответы (3)


Мне кажется ошибка. Текущий черновик 0x не указывает, что это должно быть так, как и документация MSDN.

person Steve M    schedule 04.11.2010

Ваш ответ в основном описан здесь: Являются ли перечисления С++ подписанными или неподписанными?

Реализация вашего компилятора определяет, является ли значение перечисления подписанным или беззнаковым. Я предполагаю, что они оставили там предупреждение, так что если вы или кто-то другой используете другой компилятор, вы можете получить другое поведение.

person Khalos    schedule 04.11.2010
comment
Я думал, что добавление : signed __int8 указывает, какой базовый тип будет использовать компилятор ... эта нотация специфична для Visual Studio, и я не думаю, что какие-либо конкретные реализации компилятора переопределят это. - person Giffyguy; 04.11.2010
comment
Похоже, он использует новый синтаксис c++0x, поэтому я полагаю, что Microsoft должна позволить вам это сделать. Мне любопытно, показывает ли он предупреждение, если он использует char вместо __int8. (PS. Это не специфично для VS, это тоже есть в gcc) - person Jason Iverson; 04.11.2010
comment
@JasonIverson Да, предупреждение возникает как для char, так и даже для signed char - person Paolo M; 20.10.2015

Я использую Microsoft Visual Studio 2010. Использование «char» или «signed char» вместо «signed __int8» дает идентичные результаты, а именно C4341 для «-3» и C4369 для 0xFD
В этой другой статье MSDN ясно указано, что ": signed __int8" явно указывает базовый тип для перечислителей. При этом можно предположить, что это предупреждение существует просто с целью информирования разработчика о возможных несовместимостях с другими компиляторами.

person Giffyguy    schedule 04.11.2010