1

yop,


Voici une situation :
Je compile source.c, qui inclut header1.h, qui lui-même inclut header2.h, qui lui-même inclut header1.h.

Question : y a-t-il des compilateurs qui supportent ça, ou c'est d'office considéré comme une inclusion récusrive, et donc interdit ?
On pourrait très bien immaginer par exemple, que header2.h définit un symbole qui empêche son inclusion à nouveau, donc on n'aurait pas d'inclusion récursive, mais comment le détecter ?

Est-ce que les compilateurs rejettent d'office ce genre de cas ?
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

2

Je ne sais pas trop si le préprocesseur détecte ça, ni même s'il est supposé le faire (théoriquement, on pourrait faire un fichier include qui se comporte différemment suivant le nombre de fois où il est inclus, même si je n'ai pas d'exemple réel en tête).

La solution usuelle pour éviter ça, c'est de définir un symbole, et d'inclure tout le contenu du .h dans un #ifndefdif
 : #ifndef FOLCO_H
    #define FOLCO_H

    (...déclarations...)

#en

Y'a une variante moins portable aussi : http://en.wikipedia.org/wiki/Pragma_once
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3

Ouep, je fais toujours ça bien sûr. On peut faire un pragma once aussi. (pas vu ta dernière phrase sick)

En fait, c'est pas une solution que je cherche, c'est la manière dont doit se conduire un préprocesseur ou un assembleur. Doit-il interdire un tel comportement, ou le permet-il. Dans ce cas, comment fait-il pour ne pas boucler jusqu'à épuisement de la mémoire ?

Perso j'ai écrit ça, qui recherche dans la liste des fichiers en cours d'assemblage, et qui permet l'inclusion seulement si le dernier fichier identique à celui qu'on essaie d'inclure a été fini de parser. Autrement, on est dans une inclusion récursive :
\Check:	suba.l	#FILE.sizeof,a0
	cmp.w	FILE.Handle(a0),d3
	bne.s	\NotSameFile
		btst.b	#FILE.Flags.Parsed,FILE.Flags(a0)
		beq.s	\RecursiveInclusion
\NotSameFile:
	btst.b	#FILE.Flags.BaseFile,FILE.Flags(a0)
	beq.s	\Check					; Base File not reached, continue to check
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

4

Folco (./3) :
comment fait-il pour ne pas boucler jusqu'à épuisement de la mémoire ?
Mais qui te dit que ce n'est pas le cas ? Tu as essayé ? ^^

Bon OK, sur TI89 c'est probablement pas une bonne idée de laisser un programme épuiser toute la RAM.

Une solution simple est de limiter explicitement le nombre d'inclusions récursives (par exemple, 16 niveaux).

Si le fait d'avoir une limite arbitraire ne te plaît pas, tu peux faire ça :
1) tu crées une liste chaînée
2) quand tu commences à traiter un fichier, tu regardes si le nom complet du fichier est déjà dans la liste
3) si oui, alors il y a une dépendance circulaire -> erreur
4) si non, tu ajoutes le nom complet du fichier à la liste
5) pendant le parsing du fichier, pour chaque include, tu reprends récursivement au point 2 avec le fichier inclus (sans effacer la liste)
6) une fois le parsing terminé, tu effaces le fichier de la liste
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

5

C'est exactement ce que je fais, sauf que je supprime pas les fichiers de la liste, je leur colle un flag PARSED. Auquel cas, la vérification d'inclusion les ignore (c'est le code que j'ai posté au-dessus)
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

6

Ah, j'avais lu le code trop vite ^^

Ben c'est très bien ça smile
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

7

Folco (./1) :
Question : y a-t-il des compilateurs qui supportent ça, ou c'est d'office considéré comme une inclusion récusrive, et donc interdit ?

Oui c'est autorisé.
Folco (./1) :
On pourrait très bien immaginer par exemple, que header2.h définit un symbole qui empêche son inclusion à nouveau, donc on n'aurait pas d'inclusion récursive, mais comment le détecter ?

Ce n'est pas au compilateur de le détecter (#if #else #endif)
Il n'inclut le fichier que si le code #include est à parser.
Folco (./1) :
Est-ce que les compilateurs rejettent d'office ce genre de cas ?

Non
Zerosquare (./2) :
théoriquement, on pourrait faire un fichier include qui se comporte différemment suivant le nombre de fois où il est inclus, même si je n'ai pas d'exemple réel en tête)

J'en ai déjà fait wink

8

Et ça servait à quelque chose, ou c'était juste pour le fun ? ^^
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

9

Oui. Instanciation de template en C wink
(Voir fichier degree.c ou iterator.c de maylib)

10

Et que le préprocesseur est-il censé faire si le codeur s'est vautré dans ses define ? Planter ? S'arrêter à une limite donnée, telle que Zerosquare l'a proposé ?
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

11

Une erreur doit être remontée dans ce cas là. Soit à cause de l'épuisement de la mémoire, soit à cause d'une profondeur max atteinte d'inclusion.

12

Ok, donc en fait j'ai fait exactement le contraire de ce qui se fait habituellement neutral A ta connaissance, ça dépend d'une norme, ou le préproc est libre de faire ça comme il l'entend ?

Merci déjà en tout cas.
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

13

Le préproc asm est libre de faire ce qu'il veut smile

14

Parfait, merci pour tout. smile
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

15

Zerosquare (./2) :
Je ne sais pas trop si le préprocesseur détecte ça, ni même s'il est supposé le faire (théoriquement, on pourrait faire un fichier include qui se comporte différemment suivant le nombre de fois où il est inclus, même si je n'ai pas d'exemple réel en tête).



Si tu ne met pas de #ifndef/#define soit tu va avoir une erreur de trop de #include imbrique, soit des erreurs de clash de redefinition & co.

Sinon le coup du .h qui fait des choses differentes si il est inclus plusieurs fois, ya des header comme ca ici au boulot, c'est vraiment moche...



#ifndef FIRST_INCLUDE # define FIRST_INCLUDE [blabla] #else /* FIRST_INCLUDE */ # ifndef SECOND_INCLUDE # define SECOND_INCLUDE [blabla2] # else /* SECOND_INCLUDE */ # ifndef THIRD_INCLUDE # define THIRD_INCLUDE [blabla3] # endif /* THIRD_INCLUDE */ # endif /* SECOND_INCLUDE */ #endif /* FIRST_INCLUDE */
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

16

nous on a aussi un header qui s'inclut lui même car on a des structures dont on veut savoir la taille avant de les utiliser. C'est horrible, et mal expliqué, mais ça marche grin

sinon dans mon proto-compilo C, les includes sont gérées récursivement jusqu'à 16 niveaux.

J'ai un tableau avec les infos des fichiers inclus, et un index. Je l'incrémente quand j'inclus, je traite les lignes lues, puis je ferme le fichier, je restaure les infos du fichier précédent et je continue. Ca fait comme une petite stack d'appels grin

17

Godzil (./15) :
Si tu ne met pas de #ifndef/#define soit tu va avoir une erreur de trop de #include imbrique

Possible, mais pas obligatoire (si le fichier est inclus par un autre, pas s'il s'inclut lui-même).
Godzil (./15) :
soit des erreurs de clash de redefinition & co

Pas sûr, si ce ne sont pas des définitions par exemple. Je suis dans le cadre de l'asm, j'inclus des .asm par exemple, ça pause aucun souci.
Ca peut remplacer une macro par exemple.


En asm, la distinction source/header est de pure forme, et ne repose sur rien de concret, il n'y a aucune différentiation faite par un préproc ou un assembleur à ce niveau.
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

18

Folco (./17) :
En asm, la distinction source/header est de pure forme, et ne repose sur rien de concret, il n'y a aucune différentiation faite par un préproc ou un assembleur à ce niveau.

En C aussi. Le compilateur s'en fou que ton fichier ce termine par c, h, ou whatever.

Et en asm tu peux aussi avoir des redefinitions, tente de definire deux fois une macro avec le meme nom...
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

19

Je sais pour les macros, c'est interdit. On peut faire des pch avec des fichiers .c ?
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

20

qu'entends tu pars pch?
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

21

Pre compilated headers. C'est très utilisé pour les gros projets : http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

22

do not want!

jamais compris à quoi ça servait ni comment ça marchait non plus . WTF header compilé grin

23

Le but est d'accélérer la compilation, et apparemment ça marche assez bien. Mais ça a l'air un poil scabreux à manipuler, même pour les gourous des makefile et autres autotools.
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

24

Ca ne sert que pour le C++, où le standard est tellement compliqué que parser des .h prend trop de temps.

25

Sinon, vu qu'un .h n'est rien d'autre qu'un .c et vice-versa, pourquoi on ne pourrais pas faire un PCC?

Apres tout

gcc -c toto.c -o tptp.pcc

et voila cheeky

(sinon effectivement le pch pour le C n'a que peux d'interet.. c'est interessant pour les monstres a la BOOST ou il faut 3h par fichier .h juste a cause des templates merdiques du C++ ou tu peux faire 1 ligne de code == 42Go de code objet
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

26

Godzil (./25) :
Sinon, vu qu'un .h n'est rien d'autre qu'un .c et vice-versa, pourquoi on ne pourrais pas faire un PCC?
C'est pas ce qu'on appelle un objet ?

C'est pas le compilo de Borland qui avait lancé les en-têtes précompilés ?

27

spectras (./26) :
Godzil (./25) :
Sinon, vu qu'un .h n'est rien d'autre qu'un .c et vice-versa, pourquoi on ne pourrais pas faire un PCC?
C'est pas ce qu'on appelle un objet ?

C'est pas le compilo de Borland qui avait lancé les en-têtes précompilés ?

Oui c'est un "objet"
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

28

GTC utilise un truc qui évoque les PCH. C'est peut-être pas précompilé, mais c'est parsé :

tigcclib.9xt ne fait que 16 lignes, qui sont grosso-modo des directives #header :
#ifndef __TIGCCLIB
#define __TIGCCLIB
(...)
#header<stdhead>
(...)
#endif

et stdhead.9xy est un fichier binaire.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.