IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

mot clé extern


Sujet :

C

  1. #21
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Je parle des tableaux de 'constantes', par exemple (table de sinus, CRC, chaines de caractères etc.)
    C'est exactement a ce style d'usage que je pensais.

  2. #22
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par souviron34
    J'aimerais juste pour que j'admette que cela est nécessaire que l'on me montre un exemple... Je ne dis pas ça pour faire mauvais ou parce que je suis buté, mais simplement réellement je pense que si on met des variables (même en termes de définitions ) dans un .h c'est qu'il y a un problème de conception..
    N'utilises-tu jamais de #define (hors compilation conditionnelle) dans des .h ?

  3. #23
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34
    je pense que si on met des variables (même en termes de définitions ) dans un .h c'est qu'il y a un problème de conception..
    Reprenons, parce que je sens qu'on tourne en rond et qu'on ne parle pas de la même chose.

    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /* help.h */
    extern char const *help;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    /* help.c */
    #include "help.h"
    char const *help = "Le lecteur de CD n'est pas un porte gobelet";
    Voilà, c'est tout ce que j'avais à dire sur le sujet.

  4. #24
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    OK bon on commence à s'entendre

    Citation Envoyé par gl
    Citation Envoyé par souviron34
    Tout est dans le différent ... Si tu as la même définition, mais un contenu différent, ça ne te jetteras pas, mais ça prendra la dernière linkée.... Donc tout dépendra de l'ordre dans lequel c'est linké, et l'un ou l'autre de toutes façons ne marchera pas correctement...
    J'ai l'impression qu'on ne parle pas tout a fait de la meme chose.
    Qu'entends-tu par "contenu different" ? Parles-tu du code de la fonction ou des parametres de la fonction ?
    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 !!

    Citation Envoyé par gl
    Citation Envoyé par souviron34
    Un .h sert à l'extérieur du module, à montrer ce qui est publique...
    Pas uniquement, les .h sont aussi utile a l'interieur d'un module. Notament entre les fichiers composant ce module.
    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
    Citation Envoyé par Emmanuel Delahaye
    Je parle des tableaux de 'constantes', par exemple (table de sinus, CRC, chaines de caractères etc.)
    C'est exactement a ce style d'usage que je pensais.
    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..

    Donc je pense que notre "différend" était plus une question de terminologie 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 )

    Donc je pense sujet clos ...

  5. #25
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34
    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...
    Bah, le linker va crier à la double définition. C'est tout. Pas de code généré, pas de problèmes.
    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.
    Une unité de compilation, c'est un fichier source et tous les fichiers inclus y afférant.

  6. #26
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Bah, le linker va crier à la double définition. C'est tout. Pas de code généré, pas de problèmes.
    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 -ed-
    Une unité de compilation, c'est un fichier source et tous les fichiers inclus y afférant.
    Oui absolument d'accord, mais quand il dit

    Citation Envoyé par gl
    Notament entre les fichiers composant ce module.
    ça veut pas dire que ce sont d'autres fichiers .h (en tous cas c'est pas ça qui es écrit)...

  7. #27
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34
    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..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include "f.h"
     
    void f(void)
    {
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "f.h"
     
    void f(void)
    {
    }
     
    int main (void)
    {
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  8. #28
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par souviron34
    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 !!
    D'accord, effectivement la le compilateur ne dira rien (puisqu'il ne verra meme pas les deux fonctions en meme temps).
    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.

    Citation Envoyé par souviron34
    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.
    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.
    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).

    Citation Envoyé par souviron34
    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..

    Donc je pense que notre "différend" était plus une question de terminologie 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 )
    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.
    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.

  9. #29
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par souviron34
    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...
    Bah, le linker va crier à la double définition. C'est tout. Pas de code généré, pas de problèmes.
    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.

  10. #30
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par gl
    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.
    Bzzt. Un Bloc Fonctionnel (BF) ou une classe (OO)

  11. #31
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par gl
    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.
    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...

    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).

  12. #32
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    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...

    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...

    Exemple :

    Premier fichier : (Test3.c)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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") ;
    }
    Second fichier : (Test2.c)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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") ;
    }
    Include correspondant à Test2 (Test2.h) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef TEST2_H 
    #define TEST2_H
     
    void MaFonction (int Val);
     
    #endif
    Maintenant le programme principal (Test1.c) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ;
    }
    Voici ce que ça donne (Linux Redhat 7.3, mais c'est pareil sur HPUX et IRIX) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 la sortie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <mydir>./test1
    TOTO
     
    <mydir>./test2
    TATA
    Et si maintenant on enlève les commentaires et met la routine dans le main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  13. #33
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    En effet, mêmes constatations avec les outils Borland .

  14. #34
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par souviron34
    ben non...
    Pour tous les avertissements, gcc utilise -W -Wall (ou alternativement, pour les versions plus recentes, -Wextra -Wall), cela peut peut-etre changer les choses.
    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.

  15. #35
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par DaZumba
    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é:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bcc32 Test1.c Test2.c Test3.c
    Bien-sûr, il y a des warnings du linker, mais ça compile et tourne au final !

  16. #36
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par DaZumba
    Pour tous les avertissements, gcc utilise -W -Wall (ou alternativement, pour les versions plus recentes, -Wextra -Wall), cela peut peut-etre changer les choses.
    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.
    il y a include "Test2.h"

  17. #37
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Un Bloc Fonctionnel (BF)
    C'est egalement une appelation que j'utilise et rencontre regulierement pour designer ce que j'apelle un module.
    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.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 1
    Dernier message: 22/11/2010, 18h00
  2. le mot clef extern ?
    Par ikuzar dans le forum Débuter
    Réponses: 4
    Dernier message: 30/07/2009, 15h50
  3. Deux questions sur le mot clé EXTERN
    Par Bleys dans le forum C++
    Réponses: 4
    Dernier message: 02/03/2008, 15h58
  4. Passage de C++ à Java (mot clef extern)
    Par grodwar dans le forum Langage
    Réponses: 5
    Dernier message: 05/05/2007, 14h06
  5. mot clé extern
    Par salseropom dans le forum C
    Réponses: 2
    Dernier message: 28/06/2006, 10h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo