Размер указан тип enum в C

уже прочитано этот вопрос, но искал что-то более конкретное.

  • есть ли способ сказать вашему компилятору конкретно, насколько широко вы хотите, чтобы ваше перечисление было?
  • если да, то как это сделать? Я знаю, как указать его в C#; аналогично ли это делается в C?
  • стоит ли это вообще делать? Когда значение перечисления передается функции, будет ли оно передано как intразмера стоимостью несмотря ни на что?

6 ответов


есть ли способ, чтобы сказать компилятору в частности, как широко вы хотите, чтобы ваш перечисление быть?

В общем случае нет. Не в стандарт С.

стоит ли это вообще делать?

Это зависит от контекста. Если вы говорите о передаче параметров функциям, то нет, это не стоит делать (см. ниже). Если речь идет о сохранении памяти при построении агрегатов из типов перечислений, то это может стоить того. Однако, в C вы можете просто использовать целочисленный тип подходящего размера вместо типа перечисления в агрегатах. В C (в отличие от c++) типы перечислений и целочисленные типы почти всегда взаимозаменяемы.

когда значение перечисления передается функции, будет ли оно передаваться как значение int-размера независимо?

многие (большинство) компиляторов в эти дни передают все параметры как значения естественного размера слова для данной аппаратной платформы. Например, на 64-разрядной платформе много компиляторов будет передавать все параметры как 64-битные значения, независимо от их фактического размера, даже если тип int имеет 32 бита на этой платформе (таким образом, он обычно не передается как значение "int-sized" на такой платформе). По этой причине нет смысла пытаться оптимизировать размеры перечислений для целей передачи параметров.


Я считаю, что есть флаг, если вы используете GCC.

-fshort-перечисления


вы можете заставить его быть менее определенного размера, определив соответствующее значение. Например, если вы хотите, чтобы ваше перечисление хранилось в том же размере, что и 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;
};

Это заставит компилятор поместить перечисление внутри символа.