Вопрос:
Привет, я хочу создать enum и структуру в c но мне нужно, чтобы мое enum внутри другой struct (чтобы избежать дублирования имени). что-то вроде этого:
#include <stdio.h> // define structure as our enum namespace typedef struct { typedef enum { Host, Cookie, Agent } Name; } header_n; typedef struct { header_n::Name key; // using top enum char value[128]; } header_t; int main() { header_t header; header.key = header_n::Agent; return 0; }
на самом деле я хочу использовать struct для моего enum а затем использовать это enum как разделенный тип в другой структуре, а затем вызывать последнюю структуру как полный тип, но я получаю эти ошибки, но я получаю ошибку
error: expected specifier-qualifier-list before ‘typedef’ typedef enum { error: expected expression before ‘:’ token header_n::Name key; // using top enum error: bit-field ‘<anonymous>’ width not an integer constant header_n::Name key; // using top enum error: bit-field ‘<anonymous>’ has invalid type error: ‘header_t {aka struct <anonymous>}’ has no member named ‘key’ header.key = header_n::Agent; error: expected expression before ‘header_n’ header.key = header_n::Agent; Лучший ответ:
Это просто невозможно. Язык C не поддерживает его. C требует, чтобы вы делали объявления типа в глобальном пространстве.
Поэтому вам просто нужно выбрать другое имя для них. Вы можете эмулировать функцию пространства имен в C++, назвав типы определенным образом, чтобы выполнить в основном одно и то же. Что-то вроде этого:
typedef enum { … } foo_name; typedef struct { foo_name name; } foo; typedef enum { … } bar_name; typedef struct { bar_name name; } bar; typedef struct { bar_name name; foo_name name; } foobar; Ответ №1
Несколько вещей:
- struct in C – не что иное, как сбор данных – у них нет “умнов”.
- Вы не можете использовать typedef в определении struct;
- Определение struct в C не создает новое пространство имен;
- C предоставляет 4 пространства имен: один для тэгов struct, union и enum, один для членов struct и union, один для ярлыков операторов и один для всех других идентификаторов (имена переменных, имена функций, имена typedef, константы перечисления и т.д.). Там нет пользовательских имен, а там нет :: обзорный оператора в C.
Вы либо должны будете определять свои типы перечислений отдельно от типов struct:
typedef enum { Host, Cookie, Agent } Name; typedef struct { Name key; char value[128] } header_t;
или, используйте enum non-typedef’d в определении struct:
typedef struct { enum key_t { Host, Cookie, Agent } key; char value[128]; } header_t; int main( void ) { header_t header; header.key = Agent; … }
Несмотря на то, что мы определили тип внутри типа header_t, enum key_t можно использовать вне его; C не ограничивает использование тега key_t только header_t (опять же, определения struct не создают новое пространство имен). Таким образом, это можно сделать так:
typedef struct { enum key_t { Host, Cookie, Agent } key; char value[128]; } header_t; int main( void ) { header_t header; header.key = Agent; enum key_t some_other_key = Cookie; … }
Вы можете оставить тег key_t:
typedef struct { enum { Host, Cookie, Agent } key; char value[128]; } header_t;
поэтому вы не можете определить новый экземпляр этого типа перечисления вне struct, но после этого определения вы можете использовать константы перечисления Host, Cookie и Agent и назначить их целочисленному объекту:
int keyval = Host;
Поскольку константы перечисления разделяют пространство имен “все другие идентификаторы”, никакие два типа enum могут использовать одни и те же константы перечисления между ними; вы не можете сделать что-то вроде
typedef enum { foo, bar, bletch } EnumType1; typedef enum { bletch, foo, bar } EnumType2;
Компилятор будет жаловаться, что каждый из bletch, foo и bar во втором определении enum уже определен. Если вы хотите использовать одни и те же имена между двумя разными типами перечислений, вам нужно будет создать для них уникальные префиксы или суффиксы:
typedef enum { T1_foo, T1_bar, T1_bletch } EnumType1; typedef enum { T2_bletch, T2_foo, T2_bar } EnumType2;