Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1821 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C]Problème d'inclusions imbriquées

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C]Problème d'inclusions imbriquées

n°1425160
b4u
Posté le 13-08-2006 à 23:37:54  profilanswer
 

Bonsoir,
 
j'ai deux headers (pour simplifier...) définis comme ça (je n'ai mis que les parties intéressantes):
 

Code :
  1. #ifndef _LAYOUT_H
  2. #define _LAYOUT_H
  3. #include "point.h"
  4. #include "plane.h"
  5. #include "scene.h"
  6. typedef struct
  7. {
  8. Plane  plane;
  9. Plane  scrollable;
  10. Point  refresh;
  11. void  *memory;
  12. } Layout;
  13. void  Layout_DrawScene(Layout *this, Scene *scene, Point *position);
  14. #endif /* _LAYOUT_H */


 
et le deuxième, qui inclut le premier:
 

Code :
  1. #ifndef _SCENE_H
  2. #define _SCENE_H
  3. #include "layout.h"
  4. #include "character.h"
  5. #include "level.h"
  6. typedef struct
  7. {
  8. Layout  screen;
  9. Level  level;
  10. Character player;
  11. } Scene;
  12. #endif /* _SCENE_H */


 
Mais ça ne compile pas, car les deux headers s'incluent l'un l'autre (j'ai déja vu la réponse quelquepart mais je n'arrive pas à remettre la main dessus) :sweat:

mood
Publicité
Posté le 13-08-2006 à 23:37:54  profilanswer
 

n°1425191
b4u
Posté le 14-08-2006 à 08:10:51  profilanswer
 

finalement je m'en suis sorti en remplaçant:

Code :
  1. #include "point.h"
  2. #include "plane.h"
  3. #include "scene.h"
  4. typedef struct
  5. {
  6. Plane  plane;
  7. Plane  scrollable;
  8. Point  refresh;
  9. void  *memory;
  10. } Layout;
  11. void  Layout_DrawScene(Layout *this, Scene *scene, Point *position);


 
par
 

Code :
  1. #include "point.h"
  2. #include "plane.h"
  3. struct sScene;
  4. typedef struct
  5. {
  6. Plane  plane;
  7. Plane  scrollable;
  8. Point  refresh;
  9. void  *memory;
  10. } Layout;
  11. void  Layout_DrawScene(Layout *this, struct sScene *scene, Point *position);


 
Si j'ai bien compris, c'est une définition incomplete de la structure, pour pouvoir utiliser un pointeur sur celle-ci sans devoir en donner la définition complète (ce qui permet d'éviter le #include "scene.h" ).
 
Maintenant, est-ce qu'il existe un moyen pour que le prototype

Code :
  1. void  Layout_DrawScene(Layout *this, struct sScene *scene, Point *position);

devienne

Code :
  1. void  Layout_DrawScene(Layout *this, Scene *scene, Point *position);

?


Message édité par b4u le 14-08-2006 à 08:13:56
n°1425197
Taz
bisounours-codeur
Posté le 14-08-2006 à 09:25:05  profilanswer
 

bah voilà, ça s'appelle une forward declaration.

n°1425259
b4u
Posté le 14-08-2006 à 12:46:31  profilanswer
 

oui
sinon j'aimerai bien arriver à ça:

Code :
  1. #include "point.h"
  2. #include "plane.h"
  3. Scene; /* je veux manipuler le type Scene, plutot que struct sScene */
  4. typedef struct
  5. {
  6. Plane  plane;
  7. Plane  scrollable;
  8. Point  refresh;
  9. void  *memory;
  10. } Layout;
  11. void  Layout_DrawScene(Layout *this, Scene *scene, Point *position); /* comme ça j'ai un prototype cohérent avec le reste de l'interface */


mais c'est quoi la bonne syntaxe?


Message édité par b4u le 14-08-2006 à 12:53:24
n°1425263
skelter
Posté le 14-08-2006 à 13:08:19  profilanswer
 

avec un typedef ?
 
struct Scene;
typedef struct Scene Scene;
 
pour l'histoire des includes, imagine qu'au final tout dois etre dans un seul fichier, donc tu ne peux pas inclure l'un avant l'autre et vice-versa, ca n'a pas de sens et en plus tu mets des 'includes gardes' donc ca veut dire que tu ne comprend pas ce que tu ecris

n°1425275
b4u
Posté le 14-08-2006 à 13:42:56  profilanswer
 

si justement, les "includes gardés" protègent contre les multiples inclusions, ce qui permet d'inclure un header dès qu'on veut manipuler les types qu'il définit (ce que je fais toujours, pour des raisons de lisibilités). Un code lisible est plus maintenable, si tu met tout dans un seul fichier tu sera le seul (et encore) à pouvoir faire évoluer ton code...
 
struct Scene;
typedef struct Scene Scene;
 
ok mais je voulais justement éviter de définir Scene en dehors du header qui lui est dédié

Message cité 1 fois
Message édité par b4u le 14-08-2006 à 13:45:25
n°1425311
skelter
Posté le 14-08-2006 à 14:48:43  profilanswer
 

b4u a écrit :

si justement, les "includes gardés" protègent contre les multiples inclusions, ce qui permet d'inclure un header dès qu'on veut manipuler les types qu'il définit (ce que je fais toujours, pour des raisons de lisibilités).


 
je parlais pas de ca, si tu mets des includes gardes dans 2 fichiers qui s'inclusent mutuellement, il y a comme un probleme de comprehension sur la precompilation
 

Citation :

Un code lisible est plus maintenable, si tu met tout dans un seul fichier tu sera le seul (et encore) à pouvoir faire évoluer ton code...


 
quand j'ai dit de tout mettre dans un seul fichier ? j'ai dit qu'apres la precompilation un seul le contenu du .c et des .h inclus se retrouve dans un seul fichier qui correspond au flux textuel de l'unité de traduction, si tu raisonne comme ca tu peux comprendre pourquoi ca n'a aucun sens que 2 fichiers sinclusent mutuellement, avec les includes gardes l'un des 2 includes est ignoré et sans ca part dans un dévellopement d'include "infinie" (en fait limité à 256 je crois)
 

Citation :

ok mais je voulais justement éviter de définir Scene en dehors du header qui lui est dédié


 
dans ce cas de figure on peut tout mettre dans un meme en-tete

n°1425318
b4u
Posté le 14-08-2006 à 15:18:51  profilanswer
 

je vais reformuler le probleme pour éviter qu'on aie a jouer sur les mots:
quelle est la meilleure façon de structurer les fichiers d'en-tete pour éviter les problemes de compilation liés aux forward declarations, sans bousiller l'interface et la structure du code?
par interface je veux dire: définition d'un unique type de donnée et déclaration de son set de fonction associé, le tout clairement lisible, en un ou plusieurs fichiers .h formant un truc homogène?


Message édité par b4u le 14-08-2006 à 15:22:11
n°1425335
skelter
Posté le 14-08-2006 à 16:24:20  profilanswer
 

tu peux faire comme ca pour scene.h
 

Code :
  1. #ifdef SCENE_FORWARD_DECLARATION
  2. #undef SCENE_FORWARD_DECLARATION
  3. struct Scene;
  4. typedef struct Scene Scene;
  5. #else
  6. #ifndef   SCENE_H
  7. #define  SCENE_H
  8. #include "layout.h"
  9. #include "character.h"
  10. #include "level.h"
  11. struct Scene
  12. {
  13.     Layout        screen;
  14.     Level        level;
  15.     Character    player;
  16. };
  17. #endif    /* SCENE_H */
  18. #endif /* SCENE_FORWARD_DECLARATION */


 
et dans Layout.h
 

Code :
  1. #define SCENE_FORWARD_DECLARATION
  2. #include "scene.h"


 
il y a d'autre facons de faire, tu peux par exemple faire en sorte, toujours à l'aide de directives de precompilations,
que la premiere fois que scene.h est inclus ca ne genere que la forward déclaration

n°1425343
b4u
Posté le 14-08-2006 à 17:06:46  profilanswer
 

ok merci :)
ta solution me fait penser qu'en définissant 2 fichiers .h, un pour la définition du type Scene, l'autre pour le prototype des fonctions le manipulant (pareil pour le type Layout) m'éviterait la forward declaration

Message cité 1 fois
Message édité par b4u le 14-08-2006 à 17:07:42
mood
Publicité
Posté le 14-08-2006 à 17:06:46  profilanswer
 

n°1428004
Sve@r
Posté le 20-08-2006 à 14:25:03  profilanswer
 

b4u a écrit :

ok merci :)
ta solution me fait penser qu'en définissant 2 fichiers .h, un pour la définition du type Scene, l'autre pour le prototype des fonctions le manipulant (pareil pour le type Layout) m'éviterait la forward declaration


 
Ben si le type "Scene" (déjà, il serait bien que tu nommes tes types "t_qqchose" et tes structures "s_qqchose", cela te permettra, plus tard, de moins t'embrouiller avec des identifiants de type et des identifiants de variables) est associé au type "layout", alors un seul header pour les deux serait un plus...
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C]Problème d'inclusions imbriquées

 

Sujets relatifs
[LINUX] Probleme de gcc sous le terminalLimite max de div imbriquees ?
Problème de liens survoléProblème avec Ganttproject ...
Problème UTF8 +scriptproblème avec NVU
Probléme de ???Probleme de marge
lecture de matrice et problème de flux entre C++ et VBProblème de Triggers sous Mysql 5.022
Plus de sujets relatifs à : [C]Problème d'inclusions imbriquées


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR