Размер указан тип enum в C
уже прочитано этот вопрос, но искал что-то более конкретное.
- есть ли способ сказать вашему компилятору конкретно, насколько широко вы хотите, чтобы ваше перечисление было?
- если да, то как это сделать? Я знаю, как указать его в C#; аналогично ли это делается в C?
- стоит ли это вообще делать? Когда значение перечисления передается функции, будет ли оно передано как
int
размера стоимостью несмотря ни на что?
6 ответов
есть ли способ, чтобы сказать компилятору в частности, как широко вы хотите, чтобы ваш перечисление быть?
В общем случае нет. Не в стандарт С.
стоит ли это вообще делать?
Это зависит от контекста. Если вы говорите о передаче параметров функциям, то нет, это не стоит делать (см. ниже). Если речь идет о сохранении памяти при построении агрегатов из типов перечислений, то это может стоить того. Однако, в C вы можете просто использовать целочисленный тип подходящего размера вместо типа перечисления в агрегатах. В C (в отличие от c++) типы перечислений и целочисленные типы почти всегда взаимозаменяемы.
когда значение перечисления передается функции, будет ли оно передаваться как значение int-размера независимо?
многие (большинство) компиляторов в эти дни передают все параметры как значения естественного размера слова для данной аппаратной платформы. Например, на 64-разрядной платформе много компиляторов будет передавать все параметры как 64-битные значения, независимо от их фактического размера, даже если тип int
имеет 32 бита на этой платформе (таким образом, он обычно не передается как значение "int-sized" на такой платформе). По этой причине нет смысла пытаться оптимизировать размеры перечислений для целей передачи параметров.
вы можете заставить его быть менее определенного размера, определив соответствующее значение. Например, если вы хотите, чтобы ваше перечисление хранилось в том же размере, что и int
, хотя все значения будут вписываться в char
, вы можете сделать что-то вроде этого:
typedef enum {
firstValue = 1,
secondValue = 2,
Internal_ForceMyEnumIntSize = MAX_INT
} MyEnum;
заметим, однако, что поведение может зависеть от реализации.
как вы заметили, передача такого значения функции приведет к ее расширению до int в любом случае, но если вы используете введите массив или структуру, тогда размер будет иметь значение. Если вы действительно заботитесь о размерах элементов, вы должны использовать такие типы, как int8_t
, int32_t
, etc.
есть и другой способ, если перечисление является частью структуры:
struct something {
:0;
enum whatever field:CHAR_BIT;
:0;
};
: 0; можно опустить, если поле перечисления окружено нормальными полями. Если раньше было другое битовое поле, то :0 заставит выравнивание байтов к следующему байту для следующего за ним поля.
Это зависит от значения для перечислений.
Ex: Если значение больше 2^32-1 сохраняется, размер, выделенный для общего перечисления, изменится на следующий размер.
хранить значение 0xffffffffffffff в переменной перечисления, он даст предупреждение, если попытается скомпилировать в 32-битной среде (округлить предупреждение) Где, как и в 64-битной компиляции, он будет успешным, а размер выделенного будет 8 байт.
другой способ-привести перечисление внутри объединения следующим образом:
union char_size {
char a;
enum {
a = 1,
b = 2,
} val;
};
Это заставит компилятор поместить перечисление внутри символа.