Вот минимальный пример того, что я пытаюсь сделать:
enum color { RED, GREEN, BLUE };
typedef enum legacy_color enum color;
int
main(void)
{
return 0;
}
Компиляция не удалась с
test.c:13:27: error: two or more data types in declaration specifiers
13 | typedef enum legacy_color enum color;
| ^~~~
test.c:13:32: warning: empty declaration with storage class specifier does not redeclare tag
13 | typedef enum legacy_color enum color;
| ^~~~~
Мотивация: мне нужно переименовать перечисление, чтобы оно соответствовало текущим соглашениям об именах в моем проекте. Старое имя должно остаться в качестве псевдонима, который будет объявлен в заголовочном файле совместимости. Возвращаясь к моему примеру, enum color { RED, GREEN, BLUE } будет в основном заголовочном файле, а typedef enum legacy_color enum color — в заголовочном файле обратной совместимости.
Единственный другой подход, который мне удалось придумать, — это #define legacy_color color, но он слишком широк и будет соответствовать вне контекста типа перечисления.
Обратите внимание, что typedef enum color legacy_color; недопустимо, поскольку тип изменился с enum legacy_color на просто legacy_color.





У вас есть синтаксис typedef наоборот. Определяемое имя идет в конце. Вы тоже не повторяйтесь enum. Использовать
typedef enum color legacy_color;
Это сделает legacy_color синонимом перечисления, которое вы определили в предыдущей строке.
enum color { RED, GREEN, BLUE };
typedef enum color legacy_color;
legacy_color foo = GREEN;
enum color bar = BLUE;
int
main(void)
{
return 0;
}
Тогда сделай это по-другому. enum legacy_color {...}; typedef enum legacy_color color;
Вы не можете определить тип enum XXX через другой.
Система typedef в C работает не так.
Когда вы создаете имя typedef, оно имеет один идентификатор, т. е. вы не можете добавлять к нему префикс enum или struct.
Итак, если вы хотите заменить enum color на enum legacy_color, вам придется провести рефакторинг.
Эх, я боялся, что так будет.
Кроме макросов, которые в этом контексте рискованны, сделать это невозможно.
Невозможно создать псевдоним только для тега enum (на самом деле нет тегов enum, есть только теги, а пространство имен тегов используется совместно между перечислениями, структурами и объединениями, что означает
enum foo конфликтует с struct foo и/или union foo, но не с простым именем foo (имя переменной или имя типа; не имеет значения)).
Если вы хотите сообщить, что псевдоним типа является перечислением, вы можете добавить слово enum в имя псевдонима типа, например, typedef enum legacy_color enum_color;.
К сожалению, это не решает проблему, поскольку нарушает обратную совместимость. Больше нет типа
enum legacy_color, а есть типlegacy_color. Я отредактировал описание, чтобы сделать это явным.