C определение препроцессора типа enum с точечным доступом к «полям»? - PullRequest
1 голос
/ 06 мая 2020

Думаю, мне нужно что-то похожее на эту публикацию для C ++ Доступ к значениям перечисления с помощью '::' в C ++ :

Я хочу: .. . получить доступ к значениям цвета как Color::Red.


В текущем C ++ (то есть C ++ 11 и выше) вы уже можете получить доступ к таким значениям перечисления:

enum Color { Red };
Color c = Color::Red;

Итак, я хотел бы знать - могу ли я сделать аналогичный уровень доступа в C, но через определение (чтобы мне не нужно было создавать дополнительную переменную)? Например, скажем, у меня есть этот код:

#include <stdio.h>

int model_type = 1;
int model_variant = 4;

int main(void) {
  printf("Hello World %d\n", model_variant);
  return 0;
}

Вместо этого я хотел бы написать что-то вроде этого:

int model_type = DEFAULT.MODEL_TYPE;
int model_variant = DEFAULT.MODEL_VARIANT;

Я знаю, что имена макросов (через Can вы используете нотацию ab в имени макроса #define? ):

Они не могут содержать точку.

... но я Я все еще хотел бы знать - может быть, есть какой-то трюк, чтобы я мог добиться чего-то вроде этого (возможность получить доступ к числовому значению c, скажем, DEFAULT.MODEL_TYPE) на уровне препроцессора в C? Мне бы нужен препроцессор, поскольку он будет просто вставлять необработанные числа там, где это необходимо - в противном случае мне нужно определить структуру, затем переменную этого типа структуры, а затем заполнить эту переменную ...

Если нет, есть ли другие варианты для аналогичного стиля ввода - скажем, доступ к полям перечисления напрямую по имени? (Я пробовал enum DEFAULTS { MODEL_TYPE =1, MODEL_VARIANT = 4 };, но DEFAULTS тогда является «необъявленным идентификатором», и поэтому DEFAULT.MODEL_TYPE тоже не будет работать - так что в этом смысле я не могу использовать его для своих целей) ...

1 Ответ

3 голосов
/ 06 мая 2020

object . foo в C означает (приблизительно) «добавить смещение (связанное с foo) к (char*)&object, преобразовать результат в указатель на тип, связанный с foo, а затем разыменовать».

В отличие от объектно-ориентированных языков программирования, C s . / -> не является оператором для доступа к объектам каким-то образом связанным с объектом.

If вы не хотите добавлять смещения к адресам lvalues, вы должны группировать вещи по-другому, например, через общий префикс:

enum DEFAULTS { DEFAULTS__MODEL_TYPE =1, DEFAULTS__MODEL_VARIANT = 4 };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...