Если Enums - время компиляции, то как работает #define с Enums? - PullRequest
0 голосов
/ 14 октября 2019

Согласно Этот вопрос , сначала обрабатываются препроцессоры, а затем обрабатываются перечисления. Я проверил это и правда!

У меня есть Enum eTypes

typedef enum
{
   eTYPE_1 = 0u,
   eTYPE_2,
   eTYPE_3,
   eTYPE_MAX
} eTypes;

Затем я определяю размер как

#define MAX_ARRAY_SIZE (2 * eTYPE_MAX)

Иобъявить массив как U8 TestArray[MAX_ARRAY_SIZE]

Согласно связанному вопросу, при обработке MAX_ARRAY_SIZE компилятор не знает eTypes. Тогда как TestArray получит правильный размер. Я вижу TestArray 6 байтов.

Ответы [ 2 ]

6 голосов
/ 14 октября 2019

Препроцессор выполняет простую замену текста (*) с

U8 TestArray[MAX_ARRAY_SIZE]

на

U8 TestArray[(2 * eTYPE_MAX)]

, которая затем обрабатывается компилятором. Компилятор вычислит постоянное значение 2 * eTYPE_MAX во время компиляции, что приводит к 2 * 3 = 6.

(*). Чтобы быть более правильным, обработка исходного кода препроцессором и компилятором немного сложнее. Препроцессор обрабатывает токены, а не случайные части входного текста. См., Например, https://stackoverflow.com/a/52468676/10622916.

. Основной вопрос, касающийся вопроса, заключается в том, что препроцессору все равно, является ли eTYPE_MAX в тексте замены значением enum, даже если замена является допустимым кодом Cна всех.

1 голос
/ 14 октября 2019

Согласно связанному вопросу, при обработке MAX_ARRAY_SIZE компилятор не знает eTypes. Тогда как TestArray получает правильный размер. Я вижу TestArray из 8 байтов.

Гм, нет. Похоже, вы неправильно читаете это замечание из принятого ответа на этот вопрос :

Препроцессор запускается до того, как компилятор узнает что-нибудь о вашем enum. Препроцессор знает только о макросах (#define).

Препроцессор не распознает константы перечисления как отличающиеся от любого другого идентификатора, но, конечно, компилятор знает о них, пока объявление enum находится в области видимости. Не смущайтесь тем фактом, что на практике оба эти инструмента обычно находятся и работают в одной и той же программе.

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

Выражение целочисленной константы должно иметь целочисленный тип и должно иметь только операнды, которые являются целочисленными константами, константами перечисления, символьными константами, выражениями sizeof, результаты которых являются целочисленными константами, выражениями _Alignofи плавающие константы, которые являются непосредственными операндами приведений. Операторы приведения в выражении с целочисленной константой должны преобразовывать только арифметические типы в целочисленные типы, кроме как как часть операнда, к оператору sizeof или _Alignof.

(C2011, 6.6 / 6)

«Целочисленное константное выражение» - это тип, необходимый для измерения обычного массива (в отличие от переменной с переменной длиной).

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