Приведение определения перечисления к 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:
- предпочтение не должно расширяться до 64 бит (потому что код находится в встроенной системе).
- из-за ограничений навыков, 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
) вместо перечисления, с #define
s используется для определения значений, которые он может принимать.
вы не можете (по крайней мере, переносимо) изменить тип перечисления. Стандарт ясно, что константа перечисления имеет тип 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)