Comment éviter l'autoinclusion ? - C++ - Programmation
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.
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.
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: |
et on met quoi comme code a la place des "..." ?
et que signie tous les _ et les majuscules pour remplacer _TOTO_1_H_ ?
Marsh Posté le 20-07-2007 à 16:13:44
_darkalt3_ a écrit : A priori il faut revoir ta conception; |
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 ?
Marsh Posté le 20-07-2007 à 16:29:52
cimourdain a écrit : |
http://www.fredosaurus.com/notes-c [...] ifdef.html
ou alors
http://www.velocityreviews.com/for [...] oblem.html
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)
Marsh Posté le 21-07-2007 à 11:27:16
cimourdain a écrit : Salut, |
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 :
|
dans toto1.h
Code :
|
dans toto1.cpp
Code :
|
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. |
Oui je comprends que ca te broute (moi aussi ), 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...).
Marsh Posté le 24-07-2007 à 09:37:53
g++ le supporte non ? (je crois avoir vu, quitte à émettre un deprecated ?)
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.
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.
Marsh Posté le 24-07-2007 à 10:39:41
ReplyMarsh Posté le 24-07-2007 à 10:40:32
Lam's a écrit : Un poil plus d'infos (juste pour référence): |
merci
Marsh Posté le 24-07-2007 à 10:44:56
cimourdain a écrit : |
"référence circulaire"
Marsh Posté le 24-07-2007 à 11:22:45
ReplyMarsh 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 ?
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...
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.
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...
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.
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
Marsh Posté le 25-07-2007 à 00:47:30
ReplyMarsh 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...
Marsh Posté le 25-07-2007 à 11:03:54
Joel F a écrit : |
là je suis entièrement d'accord
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. |
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)
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.