сужающее преобразование из int в long unsigned int {} плохо сформировано в C ++ 11

когда я запускаю приведенный ниже код — я получаю предупреждение «сужение преобразования из int в long unsigned int внутри {} плохо сформировано в C ++ 11 [-Wnarrowing]. Я использую компилятор GNU 4.8.

typedef struct TableEntry
{
unsigned long value;
const char *label;
} TableEntry;

enum FunctionType
{
NORMAL   = 0,
RANGE    = 1
};TableEntry functionTypes[] =
{
{NORMAL,   "NORMAL"},
{RANGE, "RANGE"}
};

Я не понимаю, почему компилятор рассматривает enum как int?
Это ошибка в GCC 4.8? Есть ли обходной путь?
Любая помощь приветствуется.

5

Решение

Если практично, сделайте:

enum FunctionType
{
NORMAL   = 0,
RANGE    = 1
};

typedef struct TableEntry
{
FunctionType value;
const char *label;
} TableEntry;TableEntry functionTypes[] =
{
{NORMAL,   "NORMAL"},
{RANGE, "RANGE"}
};

В противном случае измените тип в структуре на intили явно перечислите перечисление того же типа, что и в структуре.

Кстати, я думаю, что предупреждение g ++ является необоснованным и неправильным, поскольку исходный код является допустимым C ++ 03. Исправление: Насколько я понимаю, диагностика верна, и это серьезное изменение в C ++ 11. Я просто не мог в это поверить.


О соглашении об именах: все идентификаторы в верхнем регистре хороши для Java-программистов (которые привыкли к этому соглашению), но в C ++ они увеличивают вероятность случайного замещения текста. Есть и эстетические соображения. Большая победа в резервировании всех прописных букв для макросов.

7

Другие решения

Обычно базовым типом перечислений с незаданной областью является int (это может быть любой целочисленный тип, который может представлять все значения перечислителей).

Однако я не вижу сужающего преобразования, потому что тип unsigned long может представлять все значения типа int.

РЕДАКТИРОВАТЬ: Кажется, я не прав, потому что я нашел пример в Стандарте, который противоречит моему предположению

unsigned int ui1 = {-1}; // error: narrows

Поэтому unsigned int нельзя инициализировать с помощью списка инициализаторов, который содержит отрицательное число.

Таким образом, чтобы избежать предупреждения, перечисление может быть записано как

enum FunctionType : unsigned int // or unsigned long
{
NORMAL   = 0,
RANGE    = 1
};
4

  • Вы можете изменить «значение» на Int
  • или вы можете использовать новый «enum class» (c ++ 11), который строго типизирован, и объявить ваше «значение» в качестве этого типа.
2

Поскольку вы используете c ++ 11, вы можете объявить свой enum следующим образом:
enum Enum2 : unsigned char;
Это должно заставить enum работать. Тем не менее, IDEONE не имеет предупреждений / ошибок для вашего размещенного кода. Может быть, GCC слишком педантичен.

0
По вопросам рекламы [email protected]