5 votes

Comment déclarer partiellement une structure qui est typée dans un fichier d'inclusion ?

J'essaie de minimiser l'interdépendance des fichiers #include en tant que pratique générale.

Dans xxx.h j'ai :

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

Comment faire une déclinaison partielle similaire avec un struct typedef'd ? J'ai une déclaration actuelle dans un troisième #include qui ressemble à (disons dans yyy.h) :

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

Je veux juste un decl représentatif dans xxx.h qui référence le typedef :

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

Cette tentative entraîne une erreur de redéfinition du type my_data_t. (Utilisation de gcc 4.4.3 / Ubuntu 10.4) D'autres tentatives de recherche aléatoire (par exemple, ajouter '{}' à typedef) donnent également des erreurs.

Je sais que le compilateur a seulement besoin de savoir que la fonction nécessite un pointeur, donc il semble que cela devrait être possible. Jusqu'à présent, je n'ai rien trouvé qui compile sans erreur ni avertissement.

J'ai regardé les autres questions et réponses, je n'ai pas trouvé ce problème abordé. Il semble qu'il devrait y avoir un moyen bien connu de faire cela( ?!) (Je sais que je peux #include yyy.y dès que je #include xxx.h - j'essaie d'éviter de telles dépendances). Merci.

3voto

thiton Points 21303

Avez-vous essayé l'approche simple: ?

xxx.h

struct my_data_s;
typedef struct my_data_s my_data_t;

yyy.h

#include "decl.h"
struct my_data_s {
   int foo;
};

3voto

Jens Gustedt Points 40410

C99 ne permet pas de répéter une typedef C11 le fait.

Faites juste le typedef une seule fois et toujours en premier :

typedef struct my_data  my_data;

Il n'est pas non plus nécessaire de choisir des noms différents pour les struct et la balise typedef identifiant.

0voto

Art Swri Points 1168

Voici ce que notre groupe a décidé de faire. Il s'agit d'un compromis entre plusieurs exigences/désirs contradictoires. J'affiche une autre approche, afin que les lecteurs de l'article puissent choisir parmi une certaine variété. C'est la meilleure solution pour notre situation.

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

Raison d'être / Conditions

  • typedef et struct gardés ensemble
  • Un fichier .c qui utilise obj_X doit #include "obj_X.h". pour montrer que l'utilisation
  • éviter les fichiers .h incluant d'autres fichiers .h en général ; seuls les fichiers 'defs.h' sont #inclus dans les fichiers .h.
  • éviter de #inclure un fichier juste pour gérer les dépendances ; Autrement dit, évitez de #inclure obj_a.h juste parce qu'il est utilisé dans obj_b.h.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X