Разрешить циклическую зависимость определений типов - PullRequest
1 голос
/ 07 декабря 2011

После C урока я столкнулся с типовой зависимостью, которую я не знаю, как разрешить. До сих пор у нас было это:

typedef long SetStringPtr( char * );
typedef long GetStringPtr( char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

typedef struct {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
} IExample;

Нет проблем. Теперь меняется указатель на ЭТОТ указатель:

typedef long SetStringPtr( IExample *, char * );
typedef long GetStringPtr( IExample *, char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

typedef struct {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
} IExample;

Определения зависят друг от друга по кругу. Компилятор cl.exe показывает много синтаксических ошибок, потому что к тому времени, когда я использую IExample, он еще не был объявлен. Как я могу решить это?

Компилировать с cl.exe /W4.

Обновление

Спасибо - три более одинаковых ответа одновременно, я мог бы выбрать любой из них.

Итак, чтобы продолжить, какой выбор вы должны сделать, решая эту проблему? Во-первых, соглашение об именах - добавить _t к typedef с или _s (или Struct) к struct с? Наверное, дело вкуса. Затем, хотите ли вы, чтобы прямое определение было частью typedef или частью struct. Вероятно, также вопрос вкуса. Вот проблема в другой форме и три способа ее решения:

/* won't compile */
typedef struct {
        B * b;
        C * c;
} A;

typedef struct {
        A * a;
        C * c;
} B;

typedef struct {
        A * a;
        B * b;
} C;

Первое решение:

struct B_s;
struct C_s;

typedef struct {
        struct B_s * b; // typedef not available yet
        struct C_s * c; // ditto
} A;

typedef struct {
        A * a;
        struct C_s * c; // ditto
} B;

typedef struct {
        A * a;
        B * b;
} C;

Второе решение:

typedef struct B_s B;
typedef struct C_s C;

typedef struct {
        B * b;
        C * c;
} A;

// typedef struct ... B => change to:
struct {
        A * a;
        C * c;
} B_s;

// typedef struct ... C => change to:
struct {
        A * a;
        B * b;
} C_s;

И третье (и наиболее симметричное) решение:

struct A_s;
struct B_s;
struct C_s;

typedef struct A_s A;
typedef struct B_s B;
typedef struct C_s C;

struct {
        B * b;
        C * c;
} A_s;

struct {
        A * a;
        C * c;
} B_s;

struct {
        A * a;
        B * b;
} C_s;

Ответы [ 3 ]

3 голосов
/ 07 декабря 2011

Прогнозные объявить:

struct IExampleStruct;   /* <--- !! */

typedef long SetStringPtr( struct IExampleStruct *, char * );
typedef long GetStringPtr( struct IExampleStruct *, char *, long );

/* ... */

typedef struct IExampleStruct {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
} IExample;
2 голосов
/ 07 декабря 2011
typedef struct IExample_s IExample;

typedef long SetStringPtr( IExample *, char * );
typedef long GetStringPtr( IExample *, char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

struct IExample_s {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
};
1 голос
/ 07 декабря 2011

Необходимо переслать объявление структуры IExample.

//Forward Declare here
typedef struct IExample IExample_t;

typedef long SetStringPtr( IExample_t *, char * );
typedef long GetStringPtr( IExample_t *, char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

struct IExample {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
};
...