Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

changement de type au link

13 réponses
Avatar
Akeu
Bonjour,
si dans un fichier on défini
char Variable;
et dans un autre fichier on utilise
extern int Variable;
pour l'instant avec gcc je n'ai pas d'erreur ni de warning
comme faire pour éviter ce genre de bug au link ?

10 réponses

1 2
Avatar
TERENCE
"Akeu" a écrit dans le message de news:
Bonjour,
si dans un fichier on défini
char Variable;
et dans un autre fichier on utilise
extern int Variable;
pour l'instant avec gcc je n'ai pas d'erreur ni de warning
comme faire pour éviter ce genre de bug au link ?


Passer par un fichier d'entête de déclarations.

Avatar
Harpo
Akeu wrote:


Passer par un fichier d'entête de déclarations.


J'ai des fichier d'entête pour des variables utilisables par tous les
fichiers mais comme j'ai 300 fichiers , si à chaque fois que je
rajoute
une variable pour 2 fichiers je recompile mes 300 fichiers c'est pas
cool,


C'est bien de s'occuper du temps passé par le compilateur...
Et avoir 300 includes pour 100 autres lignes de source n'est pas une
bonne solution.

Il y a sans doute moyen de regrouper en un moins grand nombre de
fichiers ces variables, par exemple en regroupant ces variables en
fonction des sources dans lesquels elle sont utilisées.
Cela peut amener à revoir un peu le design du projet qui nécessite
peut_être un découpage interne parce que si les 300 sources sont au
même niveau cela devient difficile à gérer.

Je pense que TERENCE a raison et qu'il faut s'arranger pour que sa
solution soit praticable.

--
http://harpo.free.fr/


Avatar
TERENCE
"Akeu" a écrit dans le message de news:
J'ai des fichier d'entête pour des variables utilisables par tous les
fichiers mais comme j'ai 300 fichiers , si à chaque fois que je rajoute
une variable pour 2 fichiers je recompile mes 300 fichiers c'est pas cool,


Oui c'est pas cool ... de s'apercevoir au bout de 300 fichiers qu'il y a une problème dans les déclarations.

Mais, là tu me parles d'un deuxième problème : "je rajoute une variable pour 2 fichiers".

Alors que ma réponse était pour :
si dans un fichier on défini
char Variable;
et dans un autre fichier on utilise
extern int Variable;


Pour répondre correctement, il faut que tu précises ton problème.

Avatar
Akeu
J'ai des fichier d'entête pour des variables utilisables par tous les
fichiers mais comme j'ai 300 fichiers , si à chaque fois que je rajoute
une variable pour 2 fichiers je recompile mes 300 fichiers c'est pas cool,

Le Tue, 21 Feb 2006 11:15:27 +0100, TERENCE a écrit :


"Akeu" a écrit dans le message de
news:
Bonjour,
si dans un fichier on défini
char Variable;
et dans un autre fichier on utilise
extern int Variable;
pour l'instant avec gcc je n'ai pas d'erreur ni de warning comme faire
pour éviter ce genre de bug au link ?


Passer par un fichier d'entête de déclarations.



Avatar
Antoine Leca
En news:, Akeu va escriure:
J'ai des fichier d'entête pour des variables utilisables par tous les
fichiers


Bien.

mais comme j'ai 300 fichiers , si à chaque fois que je
rajoute une variable pour 2 fichiers je recompile mes 300 fichiers


Euh, là je ne suis plus.

D'abord, si tu as 300 fichiers, tu construis avec des outils genre Makefile,
non ? Le truc sympa, c'est que ces outils gèrent pour toi les dépendances,
donc ils ne vont recompiler que les fichiers qui sont potentiellement
impactés.
Si tu n'utilises pas encore ce genre d'outils, c'est l'occasion.


Ensuite, si tu utilises, mais que tous tes sources commencent par
#include "projet.h"
et que les variables globales vont toutes dans ce fameux projet.h, là tu es
mûr pour regarder le découpage de ton projet en module (et étudie au passage
l'adéquation de ton outil de contruction, sache que le make classique n'est
pas extraordinaire avec les structures multi-répertoires).


Sinon, il y a un truc pour éviter le souci que tu avais initialement.
Il faut d'abord forcer l'éditeur de liens à n'accepter qu'une seule
définition pour chaque variable (ce n'est pas le comportement par défaut
avec Unix, donc vérifie les options).

Ensuite, il faut que les déclarations (dans le xxx.h) soit de la forme
GLOBALE char c;
avec préalablement
#define GLOBALE extern
dans un entête normalement #inclus.

Enfin, tu crée une unité complémentaire, chargée de la définition des
objets, qui va #inclure tous les "xxx.h" nécessaires au bon fonctionnement,
mais qui sera précédée de
#define GLOBALE /*rien*/
De cette manière, les variables ne seront définies qu'une seule fois
(avertissement de l'éditeur de liens si ce n'est pas le cas), mais les
déclarations seront toujours les mêmes.

Variation nº1 (pour avoir des décorations)
GLOBALE(char) c;
avec normalement
#define GLOBALE(type) extern type __cdecl
et pour la définition
#define GLOBALE(type) type __export __cdecl

Variation nº2 (avec initialisation)
GLOBALE_INIT(char, c[], "ma chaîne");
avec normalement
#define GLOBALE(type, decl, init) extern type decl
et pour la définition
#define GLOBALE(type, decl, init) type __export decl = init


Dans un genre très différent, tu peux aussi essayer de compiler pour C++.


Antoine

Avatar
Harpo
Antoine Leca wrote:

et que les variables globales vont toutes dans ce fameux projet.h, là
tu es mûr pour regarder le découpage de ton projet en module (et
étudie au passage l'adéquation de ton outil de contruction, sache que
le make classique n'est pas extraordinaire avec les structures
multi-répertoires).


D'accord, je pense aussi qu'il faut se demander s'il n'est pas
intéressant de réduire au maximum les variables globales, surtout
celles qui génèrent un symbole extern (non static).
Il est difficile de s'en passer complètement en C, du fait de pas mal de
choses, mais une variable extern par sous-projet devrait suffire
généralement.


Ensuite, il faut que les déclarations (dans le xxx.h) soit de la forme
GLOBALE char c;
avec préalablement
#define GLOBALE extern
dans un entête normalement #inclus.


ARG !
J'ai proposé il n'y a pas longtemps quelque chose de ce genre en
simplifié, ça ne passe pas, Emdel trouve cela 'horrible et inutile' ;-)
http://minilien.com/?ZNIRpmLSt0

Dans un genre très différent, tu peux aussi essayer de compiler pour
C++.


J'ai fait cela pendant un petit moment, cela m'a principalement fait
rajouter des casts en plus de quelques autres problèmes spécifiques.

--
http://harpo.free.fr/

Avatar
Emmanuel Delahaye
si dans un fichier on défini
char Variable;
et dans un autre fichier on utilise
extern int Variable;
pour l'instant avec gcc je n'ai pas d'erreur ni de warning
comme faire pour éviter ce genre de bug au link ?


1 - On utilise pas de globales, sauf sous la torture.
2 - Si on a cédé, on assure la cohérence en utilisant correctement les
fichiers d'en-tête.

http://mapage.noos.fr/emdel/notes.htm#globales

--
C is a sharp tool

Avatar
Emmanuel Delahaye
J'ai des fichier d'entête pour des variables utilisables par tous les
fichiers mais comme j'ai 300 fichiers , si à chaque fois que je rajoute
une variable pour 2 fichiers je recompile mes 300 fichiers c'est pas cool,


Mauvais argument. De toutes façons, tu n'as pas le choix, ou alors, tu
bricoles, mais dans ce cas, on ne peut rien pour toi... D'autre part,
sauf cas extrêmement rares, tu ne devrais pas avoir de globales.

--
C is a sharp tool

Avatar
Harpo
Emmanuel Delahaye wrote:

sauf cas extrêmement rares, tu ne devrais pas avoir de globales.


Même si ce sont des const ?

--
http://harpo.free.fr/

Avatar
Antoine Leca
En news:43fb2f22$0$20166$, Harpo va escriure:
Antoine Leca wrote:

et que les variables globales vont toutes dans ce fameux projet.h,


D'accord, je pense aussi qu'il faut se demander s'il n'est pas
intéressant de réduire au maximum les variables globales,


Tu as raison, au lieu de faire de l'humour j'aurais dû commencer par là.
Heureusement qu'Emmanuel est parfait dans le rôle du ramasse-miettes ;-).


surtout celles qui génèrent un symbole extern (non static).


(Euh, je ne suis pas sûr que les théoriciens qui crient "mort aux globales"
fassent des exceptions pour les static.)

#define GLOBALE extern
dans un entête normalement #inclus.


ARG !
J'ai proposé il n'y a pas longtemps quelque chose de ce genre en


<USENET>
Si c'est il n'y a pas longtemps, tu peux donner l'URI directe.
<news:43a5886c$0$10567$
Sinon pour Google, il y a plus simple que la pub pour minilien:
http://groups.google.fr/group/fr.comp.lang.c/msg/f5780a6c62da5df0
donne directement le message qui t'intéresse, et avec les options tu peux
revenir au contexte du fil. Et pour finir il y a toujours selm,
http://groups.google.fr/groups?selmCa5886c$0$10567$
C'est le même que le premier mais news: est remplacé par
http://groups.google.fr/groups?selm Le Message-id s'obtient dans Google Groups en regardant le message en format
original (?dmode=source)
</USENET>

J'ai proposé il n'y a pas longtemps quelque chose de ce genre en
simplifié, ça ne passe pas, Emdel trouve cela 'horrible et inutile'
;-) http://minilien.com/?ZNIRpmLSt0


:-)
C'est certes 'horrible et inutile', exactement comme les globales.
C'est-à-dire, jusqu'au jour où c'est plus simple de faire comme cela que de
faire autrement.

En l'occurence, quand tu es arrivé au point que ton projet fasse « 300
fichiers » sans aucune gestion modulaire (même 50 c'est trop ÀMHA), il va
falloir couper dans le vif, et peut-être que les trucs que j'ai donné vont
lui servir.


Dans un genre très différent, tu peux aussi essayer de compiler pour
C++.


J'ai fait cela pendant un petit moment, cela m'a principalement fait
rajouter des casts en plus de quelques autres problèmes spécifiques.


Euh, si en passant en C++ il m'oblige à rajouter des transtypages à mon sens
inutiles, moi j'abandonne avant...
En fait, selon le style de codage, /parfois/ cela passe tout seul, et cela
peut alors être un bienfait pour le problème posé.
Mais je suis d'accord qu'en général il y a trop d'écart, et c'est plutôt une
fausse bonne idée.


Antoine


1 2