Comment éviter l'autoinclusion ?

Comment éviter l'autoinclusion ? - C++ - Programmation

Marsh Posté le 20-07-2007 à 14:02:18    

Salut,
 
J'ai un fichier toto.h que j'inclus avec un #include dans un autre fichier.
Dans toto.h y'a un #include "toto2.h", dans toto2.h y'a un #include "toto3.h" et dans toto3.h y'a un #include "toto.h".
 
D'où un probleme de bouclage a la compilation. Dans chaque fichier où ils sont inclus les .h sont indispensable car ce sont des déclarations de classes qui on un membre de type totoi: la classe toto a un membre de type toto2, la classe toto2 a un membre de type toto3 et la classe toto3 a un membre de type toto. Et c'est meme plus compliqué que ca parce que a terme certains toto auront plusieurs toto différents comme membres.

Reply

Marsh Posté le 20-07-2007 à 14:02:18   

Reply

Marsh Posté le 20-07-2007 à 14:17:22    

A priori il faut revoir ta conception;
ce genre de problème est inhérent à une mauvaise conception d'ensemble.


---------------
Töp of the plöp
Reply

Marsh Posté le 20-07-2007 à 15:54:42    

Tu peux te protéger de ca, a grand coups de gardes internes:
 
#ifndef _TOTO_1_H_
#define _TOTO_1_H_
 
...
 
#endif // _TOTO_1_H_
 
c'est même obligatoire des que ton projet commence a grossir, alors autant le mettre tout de suite.

Reply

Marsh Posté le 20-07-2007 à 16:06:12    

jojolepingouin a écrit :

Tu peux te protéger de ca, a grand coups de gardes internes:
 
#ifndef _TOTO_1_H_
#define _TOTO_1_H_
 
...
 
#endif // _TOTO_1_H_
 
c'est même obligatoire des que ton projet commence a grossir, alors autant le mettre tout de suite.


 
 
et on met quoi comme code a la place des "..." ?
 
et que signie tous les _ et les majuscules pour remplacer _TOTO_1_H_ ?

Message cité 1 fois
Message édité par cimourdain le 20-07-2007 à 16:12:38
Reply

Marsh Posté le 20-07-2007 à 16:13:44    

_darkalt3_ a écrit :

A priori il faut revoir ta conception;
ce genre de problème est inhérent à une mauvaise conception d'ensemble.


 
 
ben je sais pas j'avais pourtant fait attention a faire quelquechose de bien propre, j'avais réfléchis avant de coder. Mais quand tu fais une classe, qu'est ce qui t'empeche de l'utiliser comme attribut dans n'importe quelle autre ? en quoi c'est une mauvaise conception ?

Reply

Marsh Posté le 20-07-2007 à 16:29:52    

cimourdain a écrit :


et on met quoi comme code a la place des "..." ?
et que signie tous les _ et les majuscules pour remplacer _TOTO_1_H_ ?


http://www.fredosaurus.com/notes-c [...] ifdef.html
ou alors
http://www.velocityreviews.com/for [...] oblem.html


Message édité par jojolepingouin le 20-07-2007 à 16:30:35
Reply

Marsh Posté le 20-07-2007 à 23:02:14    

Reply

Marsh Posté le 20-07-2007 à 23:21:01    

bjone a écrit :

#pragma once


amis de la compatibilite ...

Reply

Marsh Posté le 21-07-2007 à 01:32:20    

bin écoutes, j'ai tellement mis de #ifndef pendant un moment, qu'au jour où j'ai rencontré le #pragma once j'ai trouvé ça élégant comme manière de faire.
 
alors qu'une directive spécifique (c'est ce qu'annonce un pragma) ne soit pas normalisée, je veux bien, mais ils aurait pu être un peu ouvert d'esprit avec un par exemple #include once ou j'en sais rien....
 
je trouve ça con d'avoir déjà à balayer tout le header là où le compilo pourrait s'arrêter à la première ligne (et un bricolage de derrière les fagots pour gérer le cas particulier, même si c'est mieux que rien)

Message cité 1 fois
Message édité par bjone le 21-07-2007 à 01:44:45
Reply

Marsh Posté le 21-07-2007 à 11:27:16    

cimourdain a écrit :

Salut,
 
J'ai un fichier toto.h que j'inclus avec un #include dans un autre fichier.
Dans toto.h y'a un #include "toto2.h", dans toto2.h y'a un #include "toto3.h" et dans toto3.h y'a un #include "toto.h".
 
D'où un probleme de bouclage a la compilation. Dans chaque fichier où ils sont inclus les .h sont indispensable car ce sont des déclarations de classes qui on un membre de type totoi: la classe toto a un membre de type toto2, la classe toto2 a un membre de type toto3 et la classe toto3 a un membre de type toto. Et c'est meme plus compliqué que ca parce que a terme certains toto auront plusieurs toto différents comme membres.


 
Prédéfinit tes classes dans le .h et fait l'inclusion dans le .cpp ca évite des inclusion récursive de ce type... si j'ai bien tout compris à ton probleme.
 
dans toto.h

Code :
  1. #include "toto1.h"
  2. class Ctoto
  3. {...}


 
dans toto1.h

Code :
  1. class Ctoto;                 // définit dans toto.h pour dire que la classe Ctoto existe
  2. class Ctoto1
  3. {...}


 
dans toto1.cpp

Code :
  1. #include "toto.h"      // pour dire ou est def la class Ctoto
  2. ...


Reply

Marsh Posté le 21-07-2007 à 11:27:16   

Reply

Marsh Posté le 23-07-2007 à 22:38:35    

bjone a écrit :

bin écoutes, j'ai tellement mis de #ifndef pendant un moment, qu'au jour où j'ai rencontré le #pragma once j'ai trouvé ça élégant comme manière de faire.
 
alors qu'une directive spécifique (c'est ce qu'annonce un pragma) ne soit pas normalisée, je veux bien, mais ils aurait pu être un peu ouvert d'esprit avec un par exemple #include once ou j'en sais rien....
 
je trouve ça con d'avoir déjà à balayer tout le header là où le compilo pourrait s'arrêter à la première ligne (et un bricolage de derrière les fagots pour gérer le cas particulier, même si c'est mieux que rien)


Oui je comprends que ca te broute (moi aussi  :pt1cable: ), mais imagine qu'un gars doive passer derrière toi pour changer tes #pragma en #ifndef pour migrer vers g++ par exemple... Ca va le brouter encore plus. Le mieux c'est (selon moi) de faire un petit script qui génère direct un template de fichier header et d'implémentation (avec la licence d'exploitation et tout...).

Reply

Marsh Posté le 24-07-2007 à 09:37:53    

g++ le supporte non ? (je crois avoir vu, quitte à émettre un deprecated ?)

Reply

Marsh Posté le 24-07-2007 à 10:25:40    

Un poil plus d'infos (juste pour référence):
   http://gcc.gnu.org/onlinedocs/gcc- [...] .html#SEC8
 
Par contre, cimourdain a un problème de conception. Ce qu'il nous dit est:
J'ai une barrique, qui contient un jerrican, qui contient une grosse bouteille, qui contient une barrique (qui donc contient un jerrican, qui contient ... etc.) Ca cycle, et c'est ça le problème.  

Reply

Marsh Posté le 24-07-2007 à 10:25:43    

#pragma once != include guard.
 
ce pragma ne sert qu'à dire à cl.exe de ne pas réouvrir et re-preprocesser un .h.  
 
include guard beats pragma everyday.

Reply

Marsh Posté le 24-07-2007 à 10:39:41    

bah l'include gard, laisse ouvrir et processer du vide.....

Reply

Marsh Posté le 24-07-2007 à 10:40:32    

Lam's a écrit :

Un poil plus d'infos (juste pour référence):
   http://gcc.gnu.org/onlinedocs/gcc- [...] .html#SEC8
 
Par contre, cimourdain a un problème de conception. Ce qu'il nous dit est:
J'ai une barrique, qui contient un jerrican, qui contient une grosse bouteille, qui contient une barrique (qui donc contient un jerrican, qui contient ... etc.) Ca cycle, et c'est ça le problème.  


merci :o


---------------
Töp of the plöp
Reply

Marsh Posté le 24-07-2007 à 10:44:56    

cimourdain a écrit :


 
 
ben je sais pas j'avais pourtant fait attention a faire quelquechose de bien propre, j'avais réfléchis avant de coder. Mais quand tu fais une classe, qu'est ce qui t'empeche de l'utiliser comme attribut dans n'importe quelle autre ? en quoi c'est une mauvaise conception ?


"référence circulaire"


---------------
Töp of the plöp
Reply

Marsh Posté le 24-07-2007 à 11:22:45    

mon programme n'est pas mal concu, on peut pas faire autrement.

Reply

Marsh Posté le 24-07-2007 à 11:29:29    

cimourdain a écrit :

mon programme n'est pas mal concu, on peut pas faire autrement.


Tu crois être le premier à te taper une référence circulaire ?


---------------
Töp of the plöp
Reply

Marsh Posté le 24-07-2007 à 12:18:25    

On NE PEUT PAS faire autrement on te dit. Il faut inventer un nouveau langage, ou modifier l'implémentation, mais il DOIT avoir une référence circulaire dans son modèle. Sinon, y aurait bien les pointeurs et les "forward class declaration", mais j'ai comme l'idée que ça ne résoud pas son problème...

Reply

Marsh Posté le 24-07-2007 à 12:23:04    

Lam's a écrit :

On NE PEUT PAS faire autrement on te dit. Il faut inventer un nouveau langage, ou modifier l'implémentation, mais il DOIT avoir une référence circulaire dans son modèle. Sinon, y aurait bien les pointeurs et les "forward class declaration", mais j'ai comme l'idée que ça ne résoud pas son problème...


Ah non, pas modifier l'implémentation, ca casserait tout ce qui ne marche pas.


---------------
Töp of the plöp
Reply

Marsh Posté le 24-07-2007 à 17:09:59    

la méthode de papangue fonctionne dans mon cas. Mais je comprends pas exactement tous les mécanismes qui sont en jeu... Si tu a l'explication papangue je suis preneur, histoire de pas faire des choses sans rien comprendre...

Reply

Marsh Posté le 24-07-2007 à 19:19:12    

bjone a écrit :

bah l'include gard, laisse ouvrir et processer du vide.....


 
Le probleme ets qu'il y a des situations ou ils ne sont pas équivalent.
La bonne oslution serait d'avoir les deux.  :??:  

Reply

Marsh Posté le 24-07-2007 à 22:06:46    

bjone a écrit :

bah l'include gard, laisse ouvrir et processer du vide.....

En fait tout compilateur decent detecte les include guards et ne rouvre pas le fichier.
Au pire le preprocesseur, c'est pas le truc le plus compliqué du monde.
 
En plus Herb Sutter le dit: chapitre 24
http://www.amazon.fr/Standards-pro [...] 2744071447
 
edit: g++ -> warning: #pragma once is obsolete

Message cité 2 fois
Message édité par jojolepingouin le 24-07-2007 à 22:08:49
Reply

Marsh Posté le 25-07-2007 à 00:47:30    

jojolepingouin a écrit :

Au pire le preprocesseur, c'est pas le truc le plus compliqué du monde.


  :whistle:  

Reply

Marsh Posté le 25-07-2007 à 10:58:52    

cimourdain a écrit :

la méthode de papangue fonctionne dans mon cas. Mais je comprends pas exactement tous les mécanismes qui sont en jeu... Si tu a l'explication papangue je suis preneur, histoire de pas faire des choses sans rien comprendre...


Bah tu prédéfinis ta classe, sans préciser quoi que ce soit, comme ça le précompilateur à une référence (même vide) à ta classe. Tu ne la définis qu'ensuite...


---------------
Töp of the plöp
Reply

Marsh Posté le 25-07-2007 à 11:03:54    

Joel F a écrit :


 
Le probleme ets qu'il y a des situations ou ils ne sont pas équivalent.
La bonne oslution serait d'avoir les deux.  :??:  


 
là je suis entièrement d'accord  :jap:

Reply

Marsh Posté le 25-07-2007 à 11:14:32    

jojolepingouin a écrit :

En fait tout compilateur decent detecte les include guards et ne rouvre pas le fichier.
Au pire le preprocesseur, c'est pas le truc le plus compliqué du monde.
 
En plus Herb Sutter le dit: chapitre 24
http://www.amazon.fr/Standards-pro [...] 2744071447
 
edit: g++ -> warning: #pragma once is obsolete


 
oui mais c'est bien, mais je trouve ça vilain.
 
un marqueur d'ouverture unique compact et explicite parfaitement lisible, propre, clair, c'est mieux.
 
le gros #ifndef/#define/#endif est lourd visuellement, c'est une implémentation possible (étalée dans tout le fichier) d'un fonctionnalitée, ça rajoute des lignes au sources qui peut déjà être bloated de trucs, et bonjour pour ne pas avoir de collisions de noms au #ifndef/#define (genre #define __FOO__ haha)
 
enfin c'est pas dramatique non plus... (c'est juste que le C++ c'est pas du cobol, donc rester sur une pratique historique bof je trouve ça vilain)


Message édité par bjone le 25-07-2007 à 11:15:34
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed