Как компилятор C обрабатывает перечисление? - PullRequest
2 голосов
/ 17 июня 2020

enum - тип, определяемый пользователем. В целом нет большой разницы между enum в C и C ++. За исключением областей видимости в C ++: если некоторые enum объявлены внутри функции или класса, к нему нельзя получить доступ за пределами объявленной функции / класса. Это не относится к C.

Нет разницы в декларации. Например, можно объявить новый enum следующим образом (как для C, так и для C ++):

enum newEnum { zero = 0, one, two, three };

В определении новых переменных почти нет разницы. Для определения новой переменной с новым определенным типом можно использовать следующую строку:

enum newEnum varA = zero; // though allowed to skip enum keyword in C++

Но есть один интересный момент. В C ++ нельзя добавить два значения enum и присвоить результат переменной типа enum:

varA = one + zero; // won't compile in c++

Это объяснимо: значения enum могут быть преобразованы в значения int, но не наоборот (от int до enum). Таким образом, в последнем примере компилятор не может присвоить результат суммы (с типом int) переменной varA (enum newEnum), потому что он не может скрыть int в newEnum.

Однако это возможно in C: последняя строка кода успешно компилируется. Это меня смущает. Поэтому возникает вопрос: как компилятор C обрабатывает enum? Это даже не кастомный тип для него? Это просто int?

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

В C константы перечисления (т.е. значения zero, one, two, three) имеют тип int.

Тип enum newEnum также существует, но перечислители не имеют этого типа. Тип enum newEnum - это целочисленный тип, и компилятор может выбрать размер типа, но он должен быть по крайней мере достаточно большим, чтобы содержать все определенные перечислители. В вашем примере его размер может быть 1, 2, 4, 8 или что-то еще.

Могут быть переменные и значения перечисляемого типа, например, enum newEnum x = 3; ++x;.

Перечислимый тип участвует в неявных целочисленных преобразованиях с рангом в соответствии с его размером.

0 голосов
/ 18 июня 2020

В C перечисления относятся к целочисленным типам. Из стандарта C (6.2.5 Типы)

17 Тип char, знаковые и беззнаковые целочисленные типы, а также перечисляемые типы вместе называются целочисленными типами. Целочисленные и вещественные типы с плавающей запятой вместе называются реальными типами.

В C ++ перечисления не являются целочисленными типами, однако их можно преобразовать в целочисленные типы.

В этом основное отличие C и типы перечисления C ++, если не учитывают перечисления с областью действия C ++.

Что касается этого шага

если какое-то перечисление объявлено внутри функции или класса, к нему нельзя получить доступ за пределами объявленного функция / класс. Это не применимо к C.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...