Всегда ли sizeof (enum) == sizeof (int)?

Всегда ли sizeof (enum) == sizeof (int)?

Or is it compiler dependent? Is it wrong to say, as compiler are optimized for word lengths (memory alignment) ie y int is the word-size on a particular compiler? Does it means that there is no processing penalty if I use enums, as they would be word aligned? Is it not better if I put all the return codes in an enum, as i clearly do not worry about the values it get, only the names while checking the return types. If this is the case wont #DEFINE be better as it would save memory.

Какова обычная практика? Если мне нужно передать эти типы возвращаемых данных по сети, и некоторая обработка должна быть выполнена на другом конце, что бы вы предпочли enums / # define / const ints.

РЕДАКТИРОВАТЬ - Просто проверяя в сети, поскольку complier не символически связывает макросы, как тогда люди отлаживают, сравнивают целочисленное значение с файлом заголовка?

Из ответов & # x2014; я добавляю эту строку ниже, так как мне нужны пояснения & # x2014;

"So it is implementation-defined, and sizeof(enum) might be equal to sizeof(char), i.e. 1."

Does it not mean that compiler checks for the range of values in enums, and then assign memory. I don't think so, of course I don't know. Can someone please explain me what is "might be".
 Vivek Sharma11 июл. 2009 г., 17:09
я нашел ответы от "nuriaion" и «Лулиан Себаниу»; отношение к части вопроса. Любой ps комментирует правильность.
 underscore_d16 сент. 2018 г., 18:31
Возможный дубликатWhat is the size of an enum in C?
 Vivek Sharma11 июл. 2009 г., 16:50
В сети на каком-то форуме я думал, что enum должен быть настолько маленьким, насколько это необходимо для хранения всех его значений, в данном случае 1 байт. & Quot; Это правда.
 Vivek Sharma11 июл. 2009 г., 17:02
Благодаря всему, я изучаю несколько разумных сомнений, которые, я думаю, несомненно помогут улучшить концепцию.
 Macarse11 июл. 2009 г., 16:49

Ответы на вопрос(5)

В некоторых компиляторах размер enum зависит от того, сколько записей в Enum. (менее 255 Entrys => байт, более 255 Entrys int) Но это зависит от компилятора и настроек компилятора.

 Vivek Sharma11 июл. 2009 г., 17:03
в любом случае я могу заставить это. Хороший вклад, хотя.
 14 июл. 2009 г., 22:02
Из-за этих проблем в нашем проекте (мы должны использовать очень старый компилятор C) мы решили не использовать enum. Но определить все с помощью #define
 16 сент. 2018 г., 18:28
Речь идет не о количестве членов перечислителя, а о диапазоне значений, которые они представляют. Я мог бы иметьenum содержащий 2 члена:{apples = 0, oranges = 1000}, Как вы думаете, компилятор может вписать их в любойchar (& Quot; Байт & Quot;)? Не без сопоставления между значениями перечислителя и базовыми значениями, которого, очевидно, не существует: это было бы кошмаром для реализации, производительности и использования.enum на самом деле это просто способ иметь некоторый контекстно-зависимый целочисленный тип, но иметь возможность ссылаться на его члены с помощью текстовых идентификаторов; члены хранятся как их числовые значения.

Is the sizeof(enum) == sizeof(int), always

Стандарт ANSI C гласит:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined. (6.7.2.2 Enumerationspecifiers)

Так что я бы сказал, что это означает нет.

If this is the case wont #DEFINE be better as it would save memory.

Каким образом использование определяет сохранение памяти по сравнению с использованием перечисления? Перечисление - это просто тип, который позволяет вам предоставлять больше информации компилятору. В фактическом результирующем исполняемом файле он просто превращается в целое число, так же, как препроцессор преобразует макрос, созданный с помощью#define в его стоимости.

What is the usual practise. I if i have to transport these return types over a network and some processing has to be done at the other end

Если вы планируете передавать значения по сети и обрабатывать их на другом конце, вам следует определить протокол. Определите размер в битах каждого типа, порядковый номер (в каком порядке байты) и убедитесь, что вы придерживаетесь этого и в коде клиента и сервера. Также не просто предполагайте, что, поскольку это работает, вы поняли это правильно. Может случиться так, что порядковый номер, например, на выбранных вами клиентских и серверных платформах совпадает, но это не всегда так.

 13 сент. 2017 г., 11:18
может быть, вы могли бы добавить ссылку наShould I use cstdint? для раздела сети
 11 июл. 2009 г., 17:22
Проще всего было бы просто использовать неподписанный символ. Вам не нужно беспокоиться о последовательности или кодировании таким образом.
 Vivek Sharma11 июл. 2009 г., 17:13
да, это проблема, у меня есть передача некоторого значения для использования в качестве команды по сети, и я хочу сделать его максимально эффективным и надежным, т. е. мне нужны мнения, что использовать для команды #defines или enums, диапазон команд должно быть не более 20 команд, поэтому по всем в символьном пределе. Я думаю, что я опубликую это как новый вопрос, я получил бы лучший ответ.

Нет.

Пример:Компилятор CodeSourcery

Когда вы определяете перечисление как это:

enum MyEnum1 {
A=1,
B=2,
C=3
};
// will have the sizeof 1 (fits in a char)

enum MyEnum1 {
A=1,
B=2,
C=3,
D=400
};
// will have the sizeof 2 (doesn't fit in a char)

подробности из их списка рассылки

 Vivek Sharma11 июл. 2009 г., 17:05
если это так, то это круто.
 13 сент. 2017 г., 11:23
Неплохой пример, но обе ссылкиcodesourcery.com/sgpp (1-е) иcodesourcery.com/archives/arm-gnu/msg02684.html (2-й) сломаны. (в надежде на обновление ремонта.)
 21 дек. 2011 г., 08:30
это не соответствует действительности ... это зависит от реализации ... оба кода выдают вывод как 4 в моей системе. Платформа - Ubuntu 10.04 (32-разрядная версия), компилятор gcc
Решение Вопроса

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

enum X { A, B };

// A has type int
assert(sizeof(A) == sizeof(int));

// some integer type. Maybe even int. This is
// implementation defined. 
assert(sizeof(enum X) == sizeof(some_integer_type));

Обратите внимание, что «некоторый целочисленный тип» в C99 также могут быть включены расширенные целочисленные типы (которые реализация, однако, должна документировать, если она их предоставляет). Тип перечисления - это некоторый тип, который может хранить значение любого перечислителя (A а такжеB в этом случае).

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

Перечислители не нуждаются в оперативной памяти. Только когда вы создаете переменную типа перечисления, вы можете использовать оперативную память. Просто думайте о перечислителях как о константах времени компиляции.

Я бы просто использовал тип, который может хранить значения перечислителя (я должен знать приблизительный диапазон значений заранее), приводить его и отправлять по сети. Предпочтительно тип должен быть фиксированным, напримерint32_tТаким образом, он не вступает в конфликты, когда задействованы разные машины. Или я бы напечатал номер и отсканировал его на другой стороне, что избавляет от некоторых из этих проблем.

Response to Edit

Ну, компилятор не обязан использовать любой размер. Легко видеть, что знак значений имеет значение - неподписанные типы могут иметь значительное повышение производительности в некоторых вычислениях. Ниже приведено поведение GCC4.4.0 на моей коробке

int main(void) {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned int"
  unsigned int *p = &a;
}

Но если вы назначите-1то GCC выбирает использоватьint как тип, которыйX совместим с

int main(void) {
  enum X { A = -1 };
  enum X a; // X compatible with "int"
  int *p = &a;
}

Используя опцию--short-enums GCC, что позволяет использовать наименьший тип, который по-прежнему соответствует всем значениям.

int main() {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned char"
  unsigned char *p = &a;
}
 13 июл. 2009 г., 01:27
Не совсем верно, что нет никаких различий между перечислениями и #defines: как вы сказали для #defines, компилятор даже не видит начальный токен, поскольку он заменен препроцессором на реальное значение. Хотя компилятор видит перечисления, и если вы скомпилируете код с символами отладки, отладчик покажет вам перечисляемые метки вместо их значения, что значительно облегчает отладку.
 01 февр. 2019 г., 21:43
Все эти разговоры о # define ... Если кто-то еще читает это, возьмите у гуру, что последнее, что вы хотите сделать, это использовать # define в C ++ для констант / перечислений. Я не добавляю, как и что еще использовать в комментарии, но это не # define.
 Vivek Sharma11 июл. 2009 г., 18:53
Теперь я думаю, что вместо того, чтобы хранить каждую команду в переменной unsigned char и приравнивать ее к значению, я буду хранить ее в #define, как это всегда было сделано. Перечисления столкнутся с проблемами порядка байтов. Теперь я понимаю, почему #define всегда использовался для кодов ошибок, имен состояний, команд ... и т. Д.

C99, 6.7.2.2p4 говорит

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,108) but shall be capable of representing the values of all the members of the enumeration. [...]

Сноска 108 добавляет

An implementation may delay the choice of which integer type until all enumeration constants have been seen.

Таким образом, это определяется реализацией, а sizeof (enum) может быть равен sizeof (char), то есть 1.

При выборе размера небольшого диапазона целых чисел, естьalways пенальти. Если вы сделаете его маленьким в памяти, вероятно, будет штраф за обработку; если вы сделаете его больше, будет применено космическое наказание. Это компромисс между временем и пространством.

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

 18 февр. 2016 г., 18:47
@ Norswap Я думаю, что ответ является неправильным толкованием (того же) стандарта.
 Vivek Sharma11 июл. 2009 г., 17:04
Не значит ли это, что complier проверяет диапазон значений в перечислениях, а затем назначает память. Я так не думаю, конечно, я не знаю :). Могут ли некоторые показать, пожалуйста, объясните, что такое "может быть"
 14 окт. 2012 г., 00:57
Второй ответhere дать другую версию того же стандарта, где говорится, что он должен быть совместим сint, Его версия устарела (он ссылается на черновик) или ваша?
 11 июл. 2009 г., 17:57
& quot; Компилятор делает & quot; это бесполезное утверждение. В мире много компиляторов, и некоторые делают это одним способом, а другие делают это другим способом (даже на одном и том же оборудовании). Если вы хотите знать, что делает конкретный компилятор, вы должны назвать его (включая версию и целевой процессор и операционную систему). Вполне может быть, чтоyour Компилятор всегда использует int для перечислений.

Ваш ответ на вопрос