OVH Cloud OVH Cloud

parcourir une structure

65 réponses
Avatar
Julien SCORDIA
Bonjour à tous,

J'ai une structure coucou comprenant des pointeurs. Dans certaines
conditions je cherche à allouer ou à libérer ces pointeurs. Je peux tout
faire à la main sans problème. Mais étant donné qu'un plus ou moins grand
nombre de ces pointeurs existe réellement dans la structure (du fait de
constantes préprocesseurs), j'aimerais ne pas avoir à changer mes fonctions
d'allocation et de libération de cette structure à chaque fois que je
rajoute un pointeur dans la structure ou que je change une constante
préprocesseur (par exemple).
C'est pourquoi j'aimerais pouvoir parcourir les divers pointeurs présents
dans la structure sans avoir à me soucier de leur nom, avec une sorte
d'itérateur. L'idée serait alors de tester le type du pointeur en cours, et
d'en déduire la bonne méthode d'allocation ou libération.
Comment peut-on réaliser cela en C?

Par ailleurs, je travaille sur un projet C depuis un bon moment, le
programme commence à être relativement conséquent (tout est relatif, c'est
un programme d'informatique scientifique: le nombre de lignes en ferait
sans doute sourire plus d'un sur ce forum). Un bon nombre de constantes
préprocesseurs sont bien pratiques (imbrication parfois de trois #ifdef
avec des && et || préprocesseurs), mais peuvent parfois gêner la lisibilité
et le parcours du code (sans le fameux % de vim, cela serait vraiment
laborieux). Que pensent les programmeurs professionnels et expérimentés des
constantes préprocesseur?

Merci d'avance pour vos conseils avisés,

Julien
--
"Allez, Monsieur, allez, et la foi vous viendra." (D'Alembert).

5 réponses

3 4 5 6 7
Avatar
Julien SCORDIA
Harpo wrote:

Je voulais dire que le temps passé à réfléchir n'est pas du temps perdu,
cela fait au contraire souvent gagner du temps par la suite.
Mais se jetter sur le code n'est pas ce qu'il y a de pire, une fonction
peut être récupérable comme brique d'un projet et si elle ne l'est pas
tant pis, elle libérera de la place sur le disque. Cela permet de
s'occuper les doigts pendant qu'on réfléchit en background.


Je suis d'accord avec toi. Et je pense que (surtout en informatique
scientifique?) le fait de commencer à coder fait surgir des points délicats
qui auraient pu très bien passer au travers d'une analyse préalable, même
très minutieuse. Qu'en penses-tu?

Pas forcément. La réponse est plutôt non.


Rhâzut ! j'ai fait une mauvaise hypothèse !

Dans ce cas, il est *peut-être* préférable de tester dynamiquement les
différentes caractéristiques des véhicules.
Par exemple en les mettant sur une espèce de database externe aux
programmes.

nous concernant, l'exemple suivant pourrait être une solution :
Le programme serait appelé comme cà :
$ monprog --vehicle ferrari.xml


Aujourd'hui, je n'utilise pas le format xml, mais le format
matlab/octave/scilab .m:

scalaire=2;
vecteur=[4 5.6 8 9];
matrice=[5 6 7
4 5 9
2 3 4];

Ce qui est lisible par un humain (contrairement au xml, qui doit se prête
plus aux structures arborescentes, non?)

Le programme remplit ensuite une structure dans laquelle peuvent
apparaître tous les parametres possibles et un certain nombre de
variable booléennes indiquant quelles fonctionnalités le véhicule
implémente etc. Cela peut faire une grosse structure mais même si elle


Aujourd'hui, c'est cela qui me manque dans les fichiers de config: ces
variables booléennes. Ces variables booléennes sont mes variables
préprocesseur, tu l'as compris.
Si j'arrivais à bien restructurer mon programme en plus de fonctions (cf
post en réponse à Stéphane Legras-Decussy plus bas), je pense que je
pourrais effectivement tout mettre en booléen dans un fichier de config
(style matlab pourquoi pas, auquel cas ce serait un entier égal à 0 ou 1,
ou simplement un entier représentant le numéro de véhicule).
Pour l'instant dans les fichiers de configuration .m, je n'ai que les
caractéristiques des éléments de la chaîne de traction (batterie, moteur
thermique, électrique, transmission, etc.)

Pourquoi un fichier en xml ?
1 - parce que c'est un standard et que l'on trouve des logiciels qui le
traitent un peu partout, Il serait étonnant qu'il n'y ait pas en C un


libxml2, non? (je ne connais que de nom).
Le problème de ce standard je pense, c'est qu'il ne se prête pas trop à
l'informatique scientifique, cf plus haut.
De plus, ces données ont besoin d'être visualisées graphiquement, d'où
l'utilisation quasi-obligatoire d'un matlab, scilab ou octave (qui utilise
Gnuplot). Le format .m paraît donc difficilement contournable...
Qu'en penses-tu?

parser de xml, cela évite de faire le design d'un langage et d'écrire
un parser. Mais si on veut se faire plaisir (??) on peut aussi utiliser
bison et flex.


Pour lire les fichiers matlab dans mon programme, j'ai écrit "from scratch"
les fonctions de lecture, ainsi que des fonctions d'écriture, car le
programme génère aussi des fichiers .m de résultats.
Je me suis bien embêté. À l'époque (début de ma thèse), je débutais en info,
et ne connaissais pas encore les outils tradionnellement utilisés pour
fabriquer des parsers.
En ce moment, je dois traiter des fichiers de résultats d'un banc de test
batteries. Cela représente des fichiers assez monstrueux, et Matlab montre
encore ses limites. Je dois donc faire le filtre qui va bien, il faut
mettre les données en un format facilement ingérable par Matlab, et qui
facilite l'exploitation des données. Comme tout le monde ici utilise
Matlab, j'ai choisi le format .mat de Matlab. J'écris le filtre en C++.
J'ai lu un bouquin sur le C++ en un WE y'a deux mois (une intro mais
cependant qui introduit tout un tas de notions par rapport au C), ça fait
longtemps que je voulais le faire, c'est fait. Bien sûr, vu la complexité
du C++, je suis encore bien juste, mais avec le bouquin de Stroustrup en
plus sous la main, j'arrive à avancer, j'apprends beaucoup de choses. Je ne
sais pas ce que tu penses de la STL, mais cela m'a l'air pas mal du tout
(pour l'instant j'ai utilisé vector, string, map). J'aurais pu essayer de
faire le filtre en Perl que je connais un peu, mais je voulais utiliser le
générateur de parser boost::spirit, car bison/flex me paraissaient plus
complexes:

http://spirit.sourceforge.net/

En fait, ce qui m'a attiré, c'est la qualité de la documentation sur le site
de spirit.
Au début c'était dur, mais maintenant j'en suis très satisfait.
Par contre, en vitesse d'exécution, je ne sais pas ce que ça donne par
rapport à Bison/Flex... Si tu as des échos à ce niveau-là.

Ce n'est qu'un exemple, l'important me semble être de donner à 1
programme les données qu'il a besoin et non de génèrer un programme
pour une utilisation particulière. Le programme n'a pas à connaître des


Ok

L'important est de séparer les problèmes, ceux qui tiennent à l'algo et
ceux qui tiennent à son utilisation, et séparer les langages, celui du
préprocesseur et le C proprement dit.
Cela entre dans une stratégie de découplage. Les problèmes doivent être
traité au niveau où ils doivent l'être.


Aujourd'hui, les problèmes algorithmiques sont assez bien découplés,
contrairement aux deux langages préprocesseur et C proprement dit.

Le problème reste le même si on utilise quelque chose de plus dynamique
comme dans l'ébauche de solution présentée plus haut. il me semble
incongru d'importuner Bellman avec des histoires de carburateur et d'en
truffer son algo.


Bellman est déjà séparé de ces histoires de carbu ;-) Les problèmes
algorithmiques sont assez bien découplés. Maintenant il faudrait couper
chacune des grandes fonctions en tout un tas de petites fonctions dont les
prototypes seraient à définir, afin d'éviter les cstes préprocesseur (à ce
niveau le boulot est à faire, au moins un mois à mon avis).

Je ne sais pas pourquoi tu as besoin des données dans ton algo, mettons
que ce soit pour valuer les arcs (si ce n'est pas ça, l'exemple peut
peut-être quand même s'appliquer), il appelle une fonction
value_arc(theStruct) qui lui renvoit la bonne valeur.


Quand j'ai besion d'évaluer les arcs, j'appelle une fonction et une seule,
mon graphe est complètement découplé du reste.

Si un programme n'est pas structuré en couches fonctionnelles, il
devient de plus en plus ingérable à mesure qu'on lui rajoute des
fonctionnalités.


Ok

Cela peut être entré de la ligne de commande par l'option '-D'


Oui, je suis bien sous GNU/Linux ;-) Merci pour l'info concernant gcc.
Jusqu'à maintenant je faisais un sed -i "s///" sur le fichier
parameters.h.


Ca marche, mais cela a le désavantage de modifier le .h, notamment son
time-stamp.


Oui, tu as raison, cela donne à chaque fois un petit conflit à régler après
l'update venant du serveur CVS. Merci pour l'astuce.

J'ai recensé (j'aurais peut-être dû le faire dès le début) les
endroits où les constantes préprocesseur interviennent:


Ce n'est peut-être pas la bonne manière de départ de poser la question,
ce serait plutôt "à quel moment les caractéristiques spécifiques aux
véhicule interviennent ?".
La manière dont tu formules la question sous-entend un choix
d'implémentation?


Oui, tu as raison. C'est un travail à faire, assez ardu. Faut s'y mettre à
100% pendant un bon bout de temps (et c'est pas du travail qui produit des
résultats tangibles, donc va convaincre mon chef).

1///////// Prototypes de fonction. Effectivement ce n'est pas très
lisible ;-)


(snip une 20aine de lignes comme ça)
Lorsque le nombre de paramêtres augmentent, il peut être bon de passer
une structure contenant ces paramêtres.


Oui, il faudrait passer une structure de structures ;-)

2////////// Dans le corps des fonctions.


Là cela peut se faire par des macros, ou une fonction ( éventuellement
inline ) get_it2max( ), que ABOUT_EQUAL_2( x ) soit une macro du
préproc ou une fonction qui teste une variable (ou les deux).
A ce sujet, je pense qu'il n'est pas recommandable de mettre des
Majuscules à ABOUT_EQUAL_2 du fait que le fait que ce soit une macro ou
une fonction est un choix d'implémentation qui n'interfère pas avec la
fonction qui l'utilise, fonctionnellement il s'agit d'une fonction.


Je ne suis pas sûr de comprendre concernant la remarque sur ABOUT_EQUAL_2.

On peut se demander s'il ne vaut pas mieux découper le code autrement.


C'est ce que je pense, mais y'a du boulot ;-)

Soit le programme exécutable est statique dans le sens où il ne peut
traiter qu'un type de véhicle auquel cas il faut indiquer le véhicule à
la compile, soit il peut traiter plusieurs types de véhicules auquel
cas il faut donner ce type à l'exécution..
C'est très chiant, mais obtenir les arguments de la ligne de commande
n'est pas d'une complexité insurmontable, voir le manuel de getopt,
getoptlong.


Pour ce programme, j'ai utilisé getoptlong.
Il se trouve que depuis j'ai codé un autre programme qui utilise popt (la
librairie qu'utilise l'utilitaire rpm pour traiter sa ligne de commande si
je ne m'abuse). popt me paraît être un ton au dessus.

Je n'ai pas encore eu le temps d'analyser ton bout de programme, qui
m'intéresse à ce que j'en ai vu. Ma réponse demain soir.
Merci encore pour tes remarques. Sans des gens comme toi je serais encore
une brêle totale en info (maintenant j'y suis quand même un peu moins...
Tout est relatif)... Merci internet qui m'a permis de retrouver la
satisfaction du codage que j'avais ressentie pour la première fois lors de
quelques listings recopiés (et d'autres plus improvisés) du CM1 à la
6ième/5ième sur Thomson MO5. Merci (GNU/)Linux! Bon sur cette envolée
lyrique, tardive, et sûrement peu à propos, mais heureusement enfouie au
sein d'un thread...

Julien
--
"Allez, Monsieur, allez, et la foi vous viendra." (D'Alembert).



Avatar
Harpo
Julien SCORDIA wrote:

Je suis d'accord avec toi. Et je pense que (surtout en informatique
scientifique?) le fait de commencer à coder fait surgir des points
délicats qui auraient pu très bien passer au travers d'une analyse
préalable, même très minutieuse. Qu'en penses-tu?


Je ne vois rien de spécifique à l'informatique scientifique.
Le fait de commencer à coder peut montrer des points délicats lorsqu'on
a seulement une approche de la programmation, en général (mais ce n'est
pas toujours si évident), on voit ce qui va être compliqué et ce qui ne
l'est pas.
Une approche fonctionnelle peut amener par exemple à dire :
. on écrit un parser pour récupérer les données en entrée.
. on rajoute total-mois à total-année toutes les fins de mois.
Ce sont 2 choses qui ne demandent pas le même nombre d'instructions, de
compétence etc.
Le fait de commencer a coder ne peut montrer des points délicats que si
on n'a pas une connaissance suffisante du langage. Il faut mettre en
relation le problème, le moyens techniques utilis(és/ables) et les
compétences requises.
<hs>
Il n'est pas évident de connaître tout cela, en ce moment j'écris un
truc en xslt pour faire mes pages web à partir de xml, j'ai pris ce
choix parce qu'il me paraissait convenable (w3 compliant, fonctionnel
propre sur lui, déclaratif (mais avec des if (mais pas de else),
for-each, des variables (qu'on ne peut pas modifier (parce qu'il ne
faut quand même pas non plus trop déconner !))), en 1 semaine 1/2 à 1/4
temps je n'ai réussi qu'à faire un minimum un peu trop nettement au
dessous de ce qui est acceptable. J'aurais écrit un parser à la main,
ce serait déjà packagé, livré. La raison est simple "je ne maitrise
pas".
</hs>

Il est très difficile d'analyser les choses, il y a toujours une part
d'obscurité et elle est souvent difficilement quantifiable.


Aujourd'hui, je n'utilise pas le format xml, mais le format
matlab/octave/scilab .m:

scalaire=2;
vecteur=[4 5.6 8 9];
matrice=[5 6 7
4 5 9
2 3 4];


Yapafoto !

Environ 20 lignes (pas courtes) de xml pour représenter la même chose.
Sans compter les commentaires parce que c'est plus dur à lire.


Ce qui est lisible par un humain (contrairement au xml, qui doit se
prête plus aux structures arborescentes, non?)


Très généralement, ce qu'on veut mettre dans un fichier de config peut
être représenté par un arbre, on peut considerer qu'un noeud et un
ensemble de feuilles est une liste.
Ceci dit, xml est lisible par un humain, sinon je ne vois pas pourquoi
ce serait si (inutilement parfois) verbeux?

Je ne cherche pas à défendre xml, je ne suis pas payé pour cela, son
interêt est que l'on peut trouver des outils qui vont avec (même si ces
outils ajoutent parfois plutôt une couche de verbosité qu'une couche
d'abstraction).
Bref, je ne défends pas xml pour sa nature intrinsèque et ce n'est pas
pour rien que j'ai oublié de mettre un tag xml <hs />.

Si j'arrivais à bien restructurer mon programme en plus de fonctions
(cf post en réponse à Stéphane Legras-Decussy plus bas), je pense que
je pourrais effectivement tout mettre en booléen dans un fichier de
config (style matlab pourquoi pas, auquel cas ce serait un entier égal
à 0 ou 1, ou simplement un entier représentant le numéro de véhicule).
Pour l'instant dans les fichiers de configuration .m, je n'ai que les
caractéristiques des éléments de la chaîne de traction (batterie,
moteur thermique, électrique, transmission, etc.)


Dans mon optique qui est limitée par ma méconnaissnce du problème, je
pense que tout ce qui relatif à une configuration donnée peut être
indiqué dans un fichier de config. Cela sépare les problèmes, ceux liés
à la programmation et ceux liés à une utilisation particulière.


Pourquoi un fichier en xml ?
1 - parce que c'est un standard et que l'on trouve des logiciels qui
le traitent un peu partout, Il serait étonnant qu'il n'y ait pas en C
un


libxml2, non? (je ne connais que de nom).


Tu me l'apprends, je ne connais pas en C de bibliothèques à ce sujet, il
faut voir sui elle ne sont pas trop absconses.

Le problème de ce standard je pense, c'est qu'il ne se prête pas trop
à l'informatique scientifique, cf plus haut.


Je ne suis pas d'accord, il peut se prêter à (àpeu près) tout, son
problème est qu'il est plus chiant que la mort.

De plus, ces données ont besoin d'être visualisées graphiquement, d'où
l'utilisation quasi-obligatoire d'un matlab, scilab ou octave (qui
utilise Gnuplot). Le format .m paraît donc difficilement
contournable... Qu'en penses-tu?


Je ne connais pas les possibilités de matlab qui est seulement un nom
pour moi. Il y a toujours un moyen de représenter visuellement des
données structurées en les traduisant dans un langage approprié (par
exemple dot de graphviz (ce n'est pas un logiciel libre mais il est
open-source (license ATT) et il marche)).


(...) Comme tout le
monde ici utilise Matlab, j'ai choisi le format .mat de Matlab.
J'écris le filtre en C++. J'ai lu un bouquin sur le C++ en un WE y'a
deux mois (une intro mais cependant qui introduit tout un tas de
notions par rapport au C), ça fait longtemps que je voulais le faire,
c'est fait. Bien sûr, vu la complexité du C++, je suis encore bien
juste, mais avec le bouquin de Stroustrup en plus sous la main,
j'arrive à avancer, j'apprends beaucoup de choses.


J'ai aussi lu un bouquin sur C++, je pense que le bouquin était bon car
j'ai réussi à en comprendre une bonne partie et a écrire de petits
programmes pour tester mes connaissances, C'était au siècle dernier et
comme je n'en pas eu de grande utilité j'ai un peu oublié.

Je ne sais pas ce
que tu penses de la STL, mais cela m'a l'air pas mal du tout (pour
l'instant j'ai utilisé vector, string, map). J'aurais pu essayer de
faire le filtre en Perl que je connais un peu, mais je voulais
utiliser le générateur de parser boost::spirit, car bison/flex me
paraissaient plus complexes:


Si tu veux voir un langage vraiment beau, quasiment intrinsèquement
beau, essaye Ruby http://www.ruby-doc.org/docs/ProgrammingRuby/
http://spirit.sourceforge.net/


J'ai regardé rapidement, il y a beaucoup d'autres générateurs de parsers
et ça pourrait prendre une vie entière de les comparer.


En fait, ce qui m'a attiré, c'est la qualité de la documentation sur
le site de spirit.
Au début c'était dur, mais maintenant j'en suis très satisfait.
Par contre, en vitesse d'exécution, je ne sais pas ce que ça donne par
rapport à Bison/Flex... Si tu as des échos à ce niveau-là.


Je n'ai eu que rarement à me servir de ce genre de choses, pour des
choses genre analyse de l'output d'un programme, fichier de config ou
de commandes dans un langage simple.

Je ne m'en suis pas servi depuis le millénaire dernier et mon avis doit
être relativisé, j'ai utilisé lex et Yacc puis Flex et Bison pour des
choses suffisamment simples pour que ça ne vaille pas la peine de
chercher mieux.
Les qualités me semblent être :
. Il sont très bien documentés (par texinfo).
. Ils produisent amha, des parsers performants correspondant à beaucoup
des usages que l'on peut en avoir, i.e. si tu veux faire un langage
concurrent de C++, ce n'est peut-être pas le bon choix.
. Flex a beaucoup de possibilités, notamment l'empilage des états, cela
peut faire quasiment se passer de bison (ce qui est typiquement un
mauvais choix).

Mais je ne peux pas comparer avec ce que je n'ai pas essayé. Je peux
juste dire que ce n'est pas un mauvais choix.


Aujourd'hui, les problèmes algorithmiques sont assez bien découplés,
contrairement aux deux langages préprocesseur et C proprement dit.



Ma solution est de mettre ça dans des macros dans des .h, dans le .c on
appelle juste la macro, c'est une manière de faire du découplage.


Bellman est déjà séparé de ces histoires de carbu ;-)


Je m'en réjouis pour lui ! Que dit le toubib pour ses histoires de
retard à l'allumage ?

Les problèmes
algorithmiques sont assez bien découplés. Maintenant il faudrait
couper chacune des grandes fonctions en tout un tas de petites
fonctions dont les prototypes seraient à définir, afin d'éviter les
cstes préprocesseur (à ce niveau le boulot est à faire, au moins un
mois à mon avis).


Mon conseil : Oublie qu'il existe un préprocesseur, du moins dans un
premier temps.
Il est très utile, mais pas tellement sauf dans des cas rares comme
solution à des problèmes, mais plutôt pour rendre le code plus clair.


Quand j'ai besion d'évaluer les arcs, j'appelle une fonction et une
seule, mon graphe est complètement découplé du reste.


Ok ! J'ai eu peur ...


Oui, tu as raison, cela donne à chaque fois un petit conflit à régler
après l'update venant du serveur CVS. Merci pour l'astuce.


Je déteste le mot 'astuce'. Ce n'est pas une astuce mais une
fonctionnalité qui répond à une nécessité.


Oui, tu as raison. C'est un travail à faire, assez ardu. Faut s'y
mettre à 100% pendant un bon bout de temps (et c'est pas du travail
qui produit des résultats tangibles, donc va convaincre mon chef).


Il se trouve que c'est ton chef, pas le mien (et j'en suis fort aise:-))
Je ne le connais pas mais le fait qu'il soit exigeant donc
nécessairement un peu casse-bonbons n'est pas un mauvais point.
Je suppose que le travail pour lequel tu es employé n'est pas de faire
plaisir à ton chef, généralement cela n'entre pas dans la définition
d'une fonction, s'il te donne du boulot tu le fais bien ensuite tu peux
le regarder entre 4zyeux et discuter, s'il est trop naze il n'est pas
difficile de prendre sa place :-), l'important est d'avoir quelque
chose de crédible à dire.

Il n'est pas nécessaire de se mettre à 100% du temps sur quelque chose,
c'est du temps perdu, tu réflèchis en background, réflèchir intensément
ne sert pas à grand chose.

Je ne suis pas sûr de comprendre concernant la remarque sur
ABOUT_EQUAL_2.


Moi non plus d'ailleurs, mais très généralement si quelque chose s'écrit
blah( blurb ), il s'agit fonctionnellement d'une fonction et non d'une
constante.

On peut se demander s'il ne vaut pas mieux découper le code
autrement.


C'est ce que je pense, mais y'a du boulot ;-)


Il est souvent difficile de dire d'où vient le boulot, ça peut être une
demi-journée de copier-coller et une demi-journée de tests.


Pour ce programme, j'ai utilisé getoptlong.
Il se trouve que depuis j'ai codé un autre programme qui utilise popt
(la librairie qu'utilise l'utilitaire rpm pour traiter sa ligne de
commande si je ne m'abuse). popt me paraît être un ton au dessus.


Il y a pas mal de choses dans ce genre, je disais ce qu'il y avait de de
plus standart.
Voir aussi :
http://www.gnu.org/software/gengetopt/gengetopt.html
Je n'ai pas essayé, j'écris rarement en C mais j'ai utilisé un logiciel
du même auteur qui me donne entière satisfaxtion.

--
Have fun !


Avatar
Julien SCORDIA
Harpo wrote:

// libère la mémoire et met l'argument à NULL
// (une fonction inline serait mieux.)
#define free_null( X ) { void **P = &X ;free( *P ) ; *P = NULL ; }
[snip]


Je viens de regarder ton programme. Je vois que dans la macro free_null, tu
passes par le pointeur générique (me trompe-je?). Je connais l'utilisation
du pointeur générique pour passer à une fonction plusieurs types d'objet
avec le même prototype (comme la fonction qsort). Mais là, je ne comprends
pas. Si je définis free_null ainsi:

#define free_null( X ) { free( X ) ; X = NULL ; }

Cela a l'air de marcher.
Mais quelque chose doit m'échapper...

Julien
--
"Allez, Monsieur, allez, et la foi vous viendra." (D'Alembert).

Avatar
Harpo
Julien SCORDIA wrote:

Si je définis free_null ainsi:

#define free_null( X ) { free( X ) ; X = NULL ; }

Cela a l'air de marcher.


Il m'est aussi arriver de remarquer que des choses avaient l'air de
marcher, Elles marchent d'ailleurs souvent.

Le problème vient du fait que X est évalué 2 fois, si c'est une variable
ce n'est pas bien grave.
Maintenant appelle la macro avec :
free_null( x = get_next(x) )
ou un truc comme ça.

Bon, je n'ai pas essayé, "courageux mais pas téméraire !".
Amha, dans ce cas, une fonction inline est le meilleur choix.

Avatar
Julien SCORDIA
Harpo wrote:

Le problème vient du fait que X est évalué 2 fois, si c'est une variable
ce n'est pas bien grave.
Maintenant appelle la macro avec :
free_null( x = get_next(x) )
ou un truc comme ça.


Ok, j'ai pigé! Toujours le même problème avec les macros, qui nous fait
mettre des parenthèses partout autour de leurs arguments. Avec les
pointeurs, cela impose à prendre l'adresse de X. Ok!

Merci.

--
"Allez, Monsieur, allez, et la foi vous viendra." (D'Alembert).

3 4 5 6 7