Как частично объявить структуру, которая определена как typedef в файле включения - PullRequest
5 голосов
/ 15 марта 2012

Я пытаюсь свести к минимуму взаимозависимость файлов #include в качестве общей практики.

В xxx.h у меня есть:

struct my_struct;  // partial decl to satisfy use of my_struct*
void funct(struct my_struct* ms);  // uses the partial def

Как сделать аналогичное частичное decl сtypedef'd struct?У меня есть фактическое decl в третьем #include, которое выглядит (скажем, в yyy.h):

typedef struct my_data_s {
  int ival;
  ... struct's other components ...
} my_data_t;

Я просто хочу, чтобы представитель decl в xxx.h ссылался на typedef:

typedef struct my_data_s  my_data_t;  // actual full decl is elsewhere
void funct2(my_data_t* md);   

Эта попытка вызывает ошибку 'redefinition of typedef my_data_t'.(Использование gcc 4.4.3 / Ubuntu 10.4) Другие попытки случайного поиска (например, добавление '{}' в typedef) также приводят к ошибкам.

Я знаю, что компилятору нужно только знать, что функция требует указатель,кажется, это должно быть возможно.До сих пор не было найдено ничего, что компилирует без ошибок / предупреждений.

Я посмотрел другие вопросы и ответы, не смог найти эту проблему решенной.Похоже, должен быть общеизвестный способ сделать это (?!) (я знаю, что могу #include yyy.y всякий раз, когда #include xxx.h - пытаясь избежать таких зависимостей.) Спасибо.

Ответы [ 3 ]

3 голосов
/ 15 марта 2012

C99 не позволяет повторять typedef, C11 делает.

Просто выполните typedef только один раз и всегда сначала:

typedef struct my_data  my_data;

Также естьнет необходимости выбирать разные имена для тега struct и идентификатора typedef.

3 голосов
/ 15 марта 2012

Вы пробовали простой подход:?

xxx.h

struct my_data_s;
typedef struct my_data_s my_data_t;

ггг.ч

#include "decl.h"
struct my_data_s {
   int foo;
};
0 голосов
/ 21 марта 2012

Вот что наша группа решила сделать.Он представляет собой компромисс нескольких противоречивых требований / желаний.Я публикую посты, чтобы показать другой подход, поэтому читатели поста могут выбирать.Это лучший ответ для нашей ситуации.

obj_a_defs.h

// contains the definition
// #include'd only by other .h files
...
#define ... // as needed for struct definition
...
typedef struct obj_a {
  ...
} obj_a;

obj_a.h

// contains the 'full info' about obj_a: data and behaviors
// #include'd by other .c files
...
#include "obj_a_defs.h"
...
// declares functions that implement 
// the behaviors associated with obj_a

obj_a.c

...
#include "obj_a.h"
...
// implementations of functions declared in obj_a.h

obj_b.h

// a 'user' of obj_a that uses obj_a as arg
#include "obj_a_defs.h"  // to get the typedef    
...
int some_b_funct(obj_a* obja, ...);
...

obj_b.c

// Defines the 'contract' that this implementation
// is meeting.
#include "obj_b.h"
...
// This .c file includes obj_a.h only if it
// uses the functions defined for obj_a.
// If obj_a is used only to 'pass through'
// to other modules, there's no need for 
// this include.
#include "obj_a.h"  // only if obj_b uses 
...
// obj_b's function implementations

Обоснование / Условия

  • typedef и struct хранятся вместе
  • a.c файл, который использует obj_X, должен #include "obj_X.h", чтобы показать, что при использовании
  • избегайте файлов .h, включая другие файлы .h в целом;только файлы 'defs.h' включают в себя # include'd в файлах .h.
  • избегайте # include'а для файла только для обработки зависимостей;IOW избегать # include'ing obj_a.h только потому, что он используется в obj_b.h
...