Приведение определения перечисления к unsigned int

согласно этому так пост:
каков размер перечисления в C?
типов enum есть signed int тип.

Я хотел бы преобразовать определение enum от signed int to unsigned int.

например, на моей платформе unsigned int - это 32-битные. Я хочу создать перечисление:

typedef enum hardware_register_e
{
    REGISTER_STATUS_BIT = (1U << 31U)
} My_Register_Bits_t;

мой компилятор жалуется, что приведенное выше определение выходит за пределы диапазона (что для signed int).

как объявить unsigned int enum значения?

Edit 1:

  1. предпочтение не должно расширяться до 64 бит (потому что код находится в встроенной системе).
  2. из-за ограничений навыков, C++ не допускается для этого проекта. :-(

Edit 2:

  • компилятор-это встроенный верстак IAR для ARM7.

4 ответов


к сожалению, стандарт ISO C (c99 6.4.4.3) гласит, что константы перечисления имеют тип int. Если вы компилируете вышеизложенное, например,gcc -W -std=c89 -pedantic, он выдаст предупреждение ISO C restricts enumerator values to range of ‘int’ [-pedantic]. Некоторые встроенные компиляторы могут вообще не принимать код.

если ваш компилятор более разборчив, вы можете обойти эту проблему, используя

typedef enum hardware_register_e
{
    REGISTER_STATUS_BIT = -2147483648   /* 1<<31, for 32-bit two's complement integers */
} hardware_register_t;

но он работает правильно только если int является 32-разрядным типом дополнения two в вашей архитектуре. Он находится на всех 32-разрядных и 64-разрядных архитектуры, которые я когда-либо использовал или слышал.

отредактировано для добавления: ARM7 использует дополнение 32-bit two int type, поэтому выше должно работать нормально. Я только рекомендую вам сохранить комментарий, объясняя, что фактическое значение 1<<31. Вы никогда не знаете, переносит ли кто-то код или использует другой компилятор. Если новый компилятор выдает предупреждение, комментарий к той же строке должен сделать его тривиальным для исправления. Лично я бы завернул код в условное, возможно

typedef enum hardware_register_e
{
#ifdef __ICCARM__
    REGISTER_STATUS_BIT = -2147483648   /* 1<<31, for 32-bit two's complement integers */
#else
    REGISTER_STATUS_BIT = 1 << 31
#endif
} hardware_register_t;

согласно этому сообщению SO: Каков размер перечисления в C? типов enum подписали типа int.

вещь enum типы can be int тип но они не int В C. On gcc 1), enum типы unsigned int по умолчанию.

enum константы int но enum определены типы реализации.

в вашем случае enum постоянная int но вы придание ему значения, которое не вписывается в int. Вы не можете иметь unsigned int enum константы в C, поскольку C говорит, что они int.


1) реализация gcc определила документацию типа перечисления: "обычно тип unsigned int, если в перечислении нет отрицательных значений, в противном случае int" в http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html


Проверьте, был ли у вашего компилятора параметр или ПРАГМА, чтобы сделать перечисления неподписанными. Если это не так, то вам просто нужно использовать plain unsigned int (или тип фиксированной ширины, такой как uint32_t) вместо перечисления, с #defines используется для определения значений, которые он может принимать.


вы не можете (по крайней мере, переносимо) изменить тип перечисления. Стандарт ясно, что константа перечисления имеет тип int. Чтобы избавиться от предупреждения, вы можете использовать cast:

typedef enum hardware_register_e
{
    REGISTER_STATUS_BIT = (int)(1U << 31U)
} My_Register_Bits_t;

Возможны Варианты

если это не должно быть в заголовке, вы можете использовать const объект требуемого типа вместо константы перечисления:

const unsigned int REGISTER_STATUS_BIT = (1U << 31);

в противном случае вы можете использовать define:

#define REGISTER_STATUS_BIT (1U << 31)