Partage
  • Partager sur Facebook
  • Partager sur Twitter

Le mot-clé "extern" pour une fonction

    6 mai 2024 à 19:16:27

    Salut tout le monde !

    Pendant plusieurs années je ne suis pas tombé sur le mot clé "extern" que je ne comprenais pas mais le destin a voulu que je croise sa route aujourd'hui et il m'a énormément embrouillé (c'est un euphémisme).

    Je l'ai trouvé dans une fonction hyper simple du type :

    monFichier.h

    extern int maFonction(void);

    monFichier.c

    int maFonction(void) {
      return 42;
    }


    La fonction maFonction se trouve dans une sorte de bibliothèque ou de programme tiers donc j'imagine que c'est une fonction que l'on peut include dans un projet de cette manière :

    #include "monFichier.h"
    
    int main() {
      maFonction();
      return 0;
    }

    Le code de la fonction est en C mais je travaille sur un projet en C++ c'est pourquoi je poste dans le forum C++.

    Revenons à nos moutons, je dois utiliser cette fonction toute simple dans un fichier qui a DÉJÀ quelques problèmes pendant le build mais lorsque j'include la fonction j'ai à présent des erreurs de corruption du heap à la compilation ou encore de stack buffer overrun à la compilation également.

    Lorsque je retire le mot clé extern ces erreurs disparaissent mais c'est dommage d'utiliser une bibliothèque tierce pour ensuite avoir à la recoder soi-même.

    Quand je vois ce code j'ai juste l'impression que le extern est de trop et je ne comprends pas ce qui a pu se passer dans l'esprit des développeurs pour qu'ils pensent à ajouter le mot clé extern à cet endroit-là.

    De ce que j'ai pu lire sur https://en.cppreference.com/w/cpp/language/storage_duration le mot clé "extern" est en plus inutile dans mon cas car la fonction est déclarée et définie ni dans une classe ni dans un namespace. Donc malgré le mot clé "extern" la fonction bénéficie de l'internal linkage et non l'external linkage.

    Quelqu'un pourrait-il me sauver en m'expliquant l'intérêt du mot clé extern dans mon cas ? avec pourquoi pas un exemple dans lequel il serait utile.

    Parce que là je me sens vraiment largué... :euh:

    -
    Edité par ThomasAirain 6 mai 2024 à 19:18:30

    • Partager sur Facebook
    • Partager sur Twitter
      6 mai 2024 à 20:28:26

      Bonjour,

      Le mot extern devant une déclaration ou définition de fonction n'a aucun effet. Il indique que l'entité à un "external linkage" ce qui est le cas par défaut des fonctions.

      Par contre, je suis très étonné que ton code mélanges des fonctions C et C++ sans précautions particulière. Par exemple dans le code que tu présentes, si le main() est dans un fichier C++, il y a erreur à l'édition des liens car :
      - ton include déclare une fonction nommée maFonction() (avec ou sans extern devant)
      - le code C défini une fonction C appelée maFonction()
      - le code de main() en C++ recherche une fonction C++ appelée maFonction()
      On a l'erreur "la fonction C++ maFonction()" est introuvable. Les 2 langages ne se mélangent pas si facilement.

      Si ça compile, c'est peut-être qu'il y a les 2 fonctions maFonction(), dont une serait dans ce que tu appelles "une sorte de bibliothèque ou de programme tiers".
      Peut-être que tu n'as pas copié l'intégralité du fichier d'entête.
      Avec les informations fournies, je manque d'informations pour plus t'aider.

      • Partager sur Facebook
      • Partager sur Twitter
        6 mai 2024 à 20:53:28

        Une fonction C peut être utilisé en C++ en la déclarant extern "C"

        extern "C" int maFonction(void);

        ou déclarée dans un bloc comme ceci :

        extern "C" {
          int maFonction(void);
        }

        ou comme ceci pour compiler aussi bien en C que C++

        #ifdef __cplusplus
        extern "C" {
        #endif
        
          int maFonction(void);
        
        #ifdef __cplusplus
        }
        #endif

        Par contre sans ça, extern ou pas ça n'aurai pas du compiler comme a dit Dalfab. 

        -
        Edité par rouIoude 6 mai 2024 à 20:56:24

        • Partager sur Facebook
        • Partager sur Twitter
        ...
          8 mai 2024 à 9:25:51

          Bonjour,

           Une remarque et question de néophyte :

           rouIoude a écrit :

          ...Par contre sans ça, extern ou pas ça n'aurai pas du compiler comme a dit Dalfab...

          Sauf erreur de ma part, le code "C" est compatible du code "C++" (en très grande partie), aussi un code C pourrait être compilé par un compilateur C++.

          Cependant, suivant moi, un OBJ compilé avec un compilateur C (ou une lib) et un OBJ compilé avec un compilateur C++ ne sont pas compatibles (syntaxe des références différentes). C'est donc un problème de linker, pas de compilateur.

          " extern "C" " indique au compilateur C++, que la référence à une syntaxe "C" et pas "C++".

          Est-ce que je suis OK ou KO ?

          Cordialement



          • Partager sur Facebook
          • Partager sur Twitter
            8 mai 2024 à 10:18:31

            Dedeun a écrit:

            Sauf erreur de ma part, le code "C" est compatible du code "C++" (en très grande partie), aussi un code C pourrait être compilé par un compilateur C++.

            Oui, c'est bien cela. C'est à l'édition des lien qu'il y aura une erreur. J'ai abusé du mot "compiler".

            • Partager sur Facebook
            • Partager sur Twitter
            ...
              10 mai 2024 à 1:29:34

              Bizarrement tout compile correctement chez moi.

              En gros, tout ce que je dois comprendre c'est que le mot clé extern ne change rien pour une fonction.

              • Partager sur Facebook
              • Partager sur Twitter

              Le mot-clé "extern" pour une fonction

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown