Это зависит от компилятора и может отличаться между перечислениями. Ниже приводится семантика
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
, чтобы не возникало конфликтов, когда задействованы разные машины. Или я бы напечатал номер и отсканировал его на другой стороне, что избавляет от некоторых из этих проблем.
Ответ на редактирование
Ну, компилятору не требуется использовать любой размер. Легко видеть, что знак значений имеет значение - неподписанные типы могут иметь значительное повышение производительности в некоторых вычислениях. Ниже приведено поведение GCC 4.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;
}