Указание размера типа enums в C

Уже прочитал этот связанный вопрос , но искал что-то более конкретное.

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

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

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

Было бы даже полезно?

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

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

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

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

-fshort-enums

Вы можете заставить его иметь хотя бы определенный размер, задав соответствующее значение. Например, если вы хотите, чтобы ваше перечисление было сохранено как тот же размер, что и int , хотя все значения будут соответствовать char , вы можете сделать что-то вроде этого:

 typedef enum { firstValue = 1, secondValue = 2, Internal_ForceMyEnumIntSize = MAX_INT } MyEnum; 

Обратите внимание, однако, что поведение может зависеть от реализации.

Как вы заметили, передача такого значения функции приведет к тому, что она будет расширена до int в любом случае, но если вы используете свой тип в массиве или структуре, размер будет иметь значение. Если вам действительно int8_t размеры элементов, вы должны действительно использовать такие типы, как int8_t , int32_t и т. Д.

Существует также другой способ, если перечисление является частью структуры:

 struct something { :0; enum whatever field:CHAR_BIT; :0; }; 

0: 0; может быть опущено, если поле enums окружено нормальными полями. Если есть еще бит бит раньше, то: 0 принудительно выравнивает байты к следующему байту для поля, следующего за ним.

Это зависит от значений, назначенных для перечислений.

Пример: если значение больше 2 ^ 32-1, размер, выделенный для общего enums, изменится на следующий размер.

Храните значение 0xFFFFFFFFFFFF в переменной enums, оно даст предупреждение, если попытается скомпилировать в 32-битной среде (предупреждение об отключении). Как и в 64-битной компиляции, она будет успешной и размер будет 8 байтов.

Другой способ – перечислить перечисление внутри объединения следующим образом:

 union char_size { char a; enum { a = 1, b = 2, } val; }; 

Это приведет к тому, что компилятор будет соответствовать перечислению внутри символа.