C'est exactement a ce style d'usage que je pensais.Citation:
Envoyé par Emmanuel Delahaye
Version imprimable
C'est exactement a ce style d'usage que je pensais.Citation:
Envoyé par Emmanuel Delahaye
N'utilises-tu jamais de #define (hors compilation conditionnelle) dans des .h ?Citation:
Envoyé par souviron34
Reprenons, parce que je sens qu'on tourne en rond et qu'on ne parle pas de la même chose.Citation:
Envoyé par souviron34
Personne n'a dit qu'il fallait mettre des définitions de variables dans un .h. Là c'est clair ? Je pense qu'on est tous d'accord là-dessus et que ce principe est incontestable
Par contre, il est tout à fait concevable d'autoriser l'accès en lecture seule d'une variable 'const' de portée globale à l'aide d'une déclaration placée dans un .h. OK ?
Code:
1
2
3 /* help.h */ extern char const *help;
Voilà, c'est tout ce que j'avais à dire sur le sujet.Code:
1
2
3
4 /* help.c */ #include "help.h" char const *help = "Le lecteur de CD n'est pas un porte gobelet";
OK bon on commence à s'entendre :mrgreen:
je parlais du code.... Si la fonction n'est pas déclarée extern, et que un autre module (par hasard ou par volonté) définit une fonction portant le même nom avec les mêmes paramètres, mais n'ayant pas le même code... crac boum hue !! :aie:Citation:
Envoyé par gl
Je pense simplement qu'alors on a pas la même notion de module. Pour moi un module est (salut Emmanuel ;) ) une unité de compilaton, donc un fichier.Citation:
Envoyé par gl
OK OK. Mais quand sur un forum comme ici tu parles qu'on peut "mettre des variables dans un header", je pense que ça porte à confusion pour beaucoup de monde..Citation:
Envoyé par gl
Donc je pense que notre "différend" était plus une question de terminologie :mrgreen: car tout à fait d'accord avec Emmanuel...
Quand vous dites "variables" ou que gl dit "tu mets pas des #define" ben pour le commun des mortels faisant du C c'est pas vraiment très clair que vous parlez de la même chose.... (et le "variable globale en lecture seule" n'était pas précisé dans le premier post de gl sur le sujet :P )
Donc je pense sujet clos ...
:king: :lahola:
Bah, le linker va crier à la double définition. C'est tout. Pas de code généré, pas de problèmes.Citation:
Envoyé par souviron34
Une unité de compilation, c'est un fichier source et tous les fichiers inclus y afférant.Citation:
Je pense simplement qu'alors on a pas la même notion de module. Pour moi un module est (salut Emmanuel ;) ) une unité de compilaton, donc un fichier.
Euhhhhh ça j'en suis pas sûr du tout.... Encore une fois prend l'exemple des prototypes de prédéclarations... 1) il crie pas du tout.. 2) il génère le code..Citation:
Envoyé par Emmanuel Delahaye
Oui absolument d'accord, mais quand il ditCitation:
Envoyé par -ed-
ça veut pas dire que ce sont d'autres fichiers .h (en tous cas c'est pas ça qui es écrit)...Citation:
Envoyé par gl
Citation:
Envoyé par souviron34
Code:
1
2
3
4
5
6 #include "f.h" void f(void) { }
Code:
1
2 void f(void);
Code:
1
2
3
4
5
6
7
8
9
10
11 #include "f.h" void f(void) { } int main (void) { return 0; }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Project : Forums Compiler : GNU GCC Compiler (called directly) Directory : C:\dev\forums2\ -------------------------------------------------------------------------------- Switching to target: default Compiling: main.c Linking console executable: console.exe .objs\dev\forums2\f.o: In function `f': C:/dev/forums2/f.c:4: multiple definition of `f' .objs\dev\forums2\main.o:C:/dev/forums2/main.c:4: first defined here collect2: ld returned 1 exit status Process terminated with status 1 (0 minutes, 0 seconds) 2 errors, 0 warnings
D'accord, effectivement la le compilateur ne dira rien (puisqu'il ne verra meme pas les deux fonctions en meme temps).Citation:
Envoyé par souviron34
Par contre dans le cas de figure que tu decris, le linker devrait emettre un avertissement [1]. Et le extern ne devrait pas changer grand chose puisque c'est un probleme d'edition de lien et non de compilation.
Pour moi un module n'est pas necessairement une unite de compilation, c'est un ensemble de fonction liee entres elles et fournissant un ensemble homogene de fonctionnalites sur un sujet precis. En gros (en vraiment tres gros), pour reprendre une denomination orientee objet, c'est un objet.Citation:
Envoyé par souviron34
L'organisation de ce module en un ou plusieurs fichiers est un probleme different (la plupart de mes "modules" n'ont qu'un seul fichier, mais pour les plus complexes le nombre augmente).
Ca me semblait tellement evident que je n'avais pas preciser "en lecture seule". C'est effectivement trompeur, j'essaierais de preciser la prochaine fois.Citation:
Envoyé par souviron34
Notons toutefois que, bien que l'usage de variables globales en lecture/ecriture est une pratique deconseillee eta eviter a tout prix (et, sauf contrainte technique particuliere, signe d'une mauvaise conception), l'usage de extern sur de telles variables est la encore indispensable. Meme si le probleme ne devrait pas se rencontrer (puisqu'on ne devrait pas avoir de telles variables).
[1] j'ai effectivement deja rencontre un cas particulier (sur Borland C++ ou Paradigm C++ je ne souviens plus), ou le cas se prioduisait (et ca m'avait bien servi a l'epoque d'ailleurs). Mais c'etait dans un cas assez special avec un compilateur pas tout recent.
J'ai deja eu un cas avec une ancienne version de Borland C++ (ou de Paradigm C++) ou le linker ne criait pas. De memoire une des fonctions etaient definies dans une bibliotheque statique et l'autre dans le code de mon application.Citation:
Envoyé par Emmanuel Delahaye
Bzzt. Un Bloc Fonctionnel (BF) ou une classe (OO)Citation:
Envoyé par gl
Ca, c'est autre chose. Les fonctions d'une bibliothèques peuvent être 'masquées' (shadowed) par une fonction applicative, oui, c'est tout à fait possible. Il suffit que les bibliothèques soient, comme il se doit, liées après les .o[bj]. Il y a une sorte de priorité données aux fonctions applicatives, les bibliothèques étant là pour boucher les trous si nécessaire...Citation:
Envoyé par gl
Par contre, je pense qu'il s'agit d'une QoI et non d'un comportement demandé par le langage C.
Mais 2 fonctions de même nom dans 2 .o[bj], ça fait une erreur de lien. C'est certain. (Vu du C : comportement indéfini).
ben non...Citation:
Envoyé par Emmanuel Delahaye
Exemple :
Premier fichier : (Test3.c)
Second fichier : (Test2.c)Code:
1
2
3
4
5
6
7
8
9
10
11 #include <stdlib.h> #include <stdio.h> #include <string.h> void MaFonction ( int Val ) { fprintf ( stderr, "TATA\n") ; }
Include correspondant à Test2 (Test2.h) :Code:
1
2
3
4
5
6
7
8
9
10
11 #include <stdlib.h> #include <stdio.h> #include <string.h> void MaFonction ( int Val ) { fprintf ( stderr, "TOTO\n") ; }
Maintenant le programme principal (Test1.c) :Code:
1
2
3
4
5
6
7 #ifndef TEST2_H #define TEST2_H void MaFonction (int Val); #endif
Voici ce que ça donne (Linux Redhat 7.3, mais c'est pareil sur HPUX et IRIX) :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <stdlib.h> #include <stdio.h> #include <string.h> #include "Test2.h" /* void MaFonction(int Val ) { fprintf ( stderr, "TUTU\n"); } */ /* ********************* main routine ********************* */ int main (int argc, char **argv) { MaFonction( 0 ); return 0 ; }
Et la sortie :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 <mydir>make teste1 ar rv "./lib1.a" Test2.o Test3.o ; r - Test2.o r - Test3.o ar ts "./lib1.a" cc -Wall -pedantic ./Test1.c -lm "./lib1.a" -o ./test1 <mydir> <mydir>make teste2 ar rv "./lib2.a" Test3.o Test2.o ; r - Test3.o r - Test2.o ar ts "./lib2.a" cc -Wall -pedantic ./Test1.c "./lib2.a" -o ./test2 <mydir>
Et si maintenant on enlève les commentaires et met la routine dans le main :Code:
1
2
3
4
5
6 <mydir>./test1 TOTO <mydir>./test2 TATA
Code:
1
2
3
4
5
6
7
8
9
10
11 <mydir>make teste1 ar rv "./lib1.a" Test2.o Test3.o ; r - Test2.o r - Test3.o ar ts "./lib1.a" cc -Wall -pedantic ./Test1.c -lm "./lib1.a" -o ./test1 <mydir> <mydir>./test1 TUTU
En effet, mêmes constatations avec les outils Borland :? .
Pour tous les avertissements, gcc utilise -W -Wall (ou alternativement, pour les versions plus recentes, -Wextra -Wall), cela peut peut-etre changer les choses.Citation:
Envoyé par souviron34
Egalement, tu triches un peu : tu devrais inclure le fichier d'interface de lib1.a (1.h) puisque tu fais le lien avec la biblio.
Dans le test que j'ai réalisé, je ne suis même pas passé par une librairie intermédiaire; pour ceux qui connaissent Borland, j'ai juste utilisé:Citation:
Envoyé par DaZumba
Bien-sûr, il y a des warnings du linker, mais ça compile et tourne au final :koi: !Code:bcc32 Test1.c Test2.c Test3.c
il y a include "Test2.h" :PCitation:
Envoyé par DaZumba
C'est egalement une appelation que j'utilise et rencontre regulierement pour designer ce que j'apelle un module.Citation:
Envoyé par Emmanuel Delahaye
A ma connaissance le terme module n'a pas de definition dans la norme C et son sens "courant" me semble bien convenir a la situation.