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 :

Prototype de fonction inline


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2013
    Messages
    31
    D�tails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 31
    Par d�faut Prototype de fonction inline
    Bonjour,

    Voil�, je me posais une petite question sur l'utilit� d'un prototype d'une fonction inline.

    J'ai lu dans la FAQ que la fonction inline doit etre d�finie dans le .h. Elle est ensuite appel�e dans les fichiers .cpp dans lesquels on en a besoin.
    Mais le prototype, est-il utile?

    Pour une fonction "classique", je voyais l'utilit� de mettre le prototype de la fonction dans le .h: On indiquait au compilateur que quelque part dans le code, on va peut etre rencontr� une fonction "toto", mais pas de panique, elle sera d�finie quelque part.

    Mais l�, on a directement la d�finition de la fonction inline dans le .h. Quel interet de mettre alors un prototype...?

    PS: J'ai fait le test: sans prototype, j'obtiens une erreur � l'�dition de lien...

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant s�curit� informatique � Dipl�m� master Droit/�conomie/Gestion
    Inscrit en
    D�cembre 2011
    Messages
    9 026
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 32
    Localisation : France, Loire (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Doctorant s�curit� informatique � Dipl�m� master Droit/�conomie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : D�cembre 2011
    Messages : 9 026
    Par d�faut
    Bonjour,

    Sans code, cela est difficile de voir ce qu'il ne va pas.

    Lorsque tu d�finis une fonction, tu (re)d�clare aussi son prototype.
    Pour une fonction inline, on mettra dans le .h :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    inline void foo(void)
    {
              //fait ce que tu veux
    }

  3. #3
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Salut,

    En fait, il faut surtout voir de quoi l'on parle car il est possible d'avoir des fonctions libres et des foncions membres.

    Et comme il est tout aussi possible d'appeler des fonctions membre depuis une fonction libre et d'appeler une fonction libre depuis une fonction membre, et que, de plus, il est possible de d�porter la d�finition de fonctions membre en dehors de la classe ou de la structure � laquelle elles appartiennent, ca fait pas mal de possibilit�s (que je vais essayer de parcourir avec toi )

    Pour une fonction libre inline, tu peux en effet fournir directement son impl�mentation, sauf si tu as une autre d�finition de fonction qui apparait AVANT ta fonction et qui l'utilise.

    A ce moment l�, il y a lieu de r�fl�chir un tout petit peu

    En effet, le compilateur parcoure le code source exactement de la mani�re dont tu lis un livre et, tout comme tu ne sais pas dire ce qui se passe � la page 11 quand tu es � la page 10, le compilateur ne connait � la ligne 10 que... ce qu'il a d�j� rencontr�.

    Mettons que tu aies deux fonctions inline : foo et bar, et que bar doive faire appel � foo.

    Le compilateur sera content s'il a rencontr� foo avant de rencontrer son appel dans bar, et donc avec un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    /* inline */ void foo(){
    /*...*/
    }
    /* inline */ void bar(){
    foo();
    }
    alors qu'il t'enverra sur les roses avec le code suivant (si tu n'as pas d�clar� le prototype de foo)
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    /* inline */ void bar(){
    foo();
    }
    /* inline */ void foo(){
    /*...*/
    }
    Le fait que la fonction soit inlin�e ou non ne change strictement rien

    Et si foo fait appel � bar et que bar fait appel � foo (c'est alors un certain type de r�cursivit� ), il est clair que tu n'auras pas le choix : il faudra fatalement fournir le prototype de la deuxi�me fonction avant d'essayer de donner l'impl�mentation de la premi�re, et ce, que ta (tes) fonctions soi(ent) d�clar�e(s) inline ou non.

    Dans le cas o� tu as une fonction membre, il faut savoir que:
    1. toute fonction d�finie directement dans le corps de la classe ou de la structure est implicitement d�clar�e inline
    2. le compilateur analyse l'ensemble de la composition de la classe ou de la structure avant de regarder � l'impl�mentation des fonctions, ce qui facilite un peu les chose
    Ainsi, les fonctions foo et bar sont implicitement d�clar�es inline dans la classe suivante
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    class MaClasse{
        public:
        void foo(){/* ... */}
        void bar(){/* ... */}
    };
    Mais, comme elles sont membres de la m�me classe ne se plaindra pas si foo appelle bar et / ou si bar appelle foo.

    Par contre, si tu veux d�porter les fonctions foo et bar sous une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MaClasse{
        public:
        void foo();
        void bar();
    };
    void MaClasse::foo(){
    /* ... */
    }
    void MaClasse::bar(){
    /* ... */
    }
    et que tu veux qu'elles soient inlin�es, il faudra
    1. fournir leur prototype dans MaClasse
    2. les d�clarer explicitement inline
    Encore une fois, le fait que l'une fasse �ventuellement appel � l'autre n'aura pas d'incidence

    Enfin, il reste le probl�me (par chance fort similaire) d'une fonction libre qui fait appel � une fonction membre et vice versa.

    Et l�, on en revient toujours au m�me point : le compilateur ne connait que ce qu'il a d�j� rencontr� dans les lignes pr�c�dentes

    Si tu veux qu'une fonction libre fasse appel � une fonction membre, il faut... que le compilateur ait d�j� rencontr� la d�finition complete de la classe ou de la structure dont la fonction membre est issue.

    Le simple fait d'avoir une d�claration anticip�e ne suffit alors plus.

    De m�me, si tu veux appeler une fonction libre depuis une fonction membre, il faudra que le compilateur ait, au minimum, d�j� rencontr� le prototype de la fonction libre lorsqu'elle sera appel�e dans la fonction membre.

    Ainsi, le compilateur t'enverra sur les roses s'il rencontre un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    class MaClasse{
        public:
        void foo(){bar();} // implicitement inline
    };
    inline void bar(){
    /*...*/
    }
    tout comme il t'enverra sur les roses s'il rencontre un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MaClasse; // seul moyen pour que le prototype de foo passe, et encore, 
                    // sous conditions
    inline void bar(MaClasse /* const */ & obj){
    obj.foo();
    }
    class MaClasse{
        public:
        void foo(){/*...*/} // implicitement inline
    };
    Et bien sur, si foo appelle bar et que bar appelle foo, tu n'es pas sorti de l'auberge

    Enfin, si tu d�portes l'impl�mentation de foo, il faudra encore r�fl�chir � l'ordre dans lequel tu d�finis foo et bar, car le compilateur refusera un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MaClasse{
        public:
        inline foo(); // explicitement inline
    }
    void MaClasse::foo(){
        bar(); // KO : le compilateur ne connait pas encore bar
    }
    void bar(MaClasse /* const &*/ obj){
        obj.foo(); //OK le compilateur connait MaClasse::foo()
    }
    alors qu'il acceptera un code proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MaClasse{
        public:
        inline foo(); // explicitement inline
    }
    void bar(MaClasse /* const &*/ obj){
        obj.foo(); //OK le compilateur connait MaClasse::foo()
    }
    void MaClasse::foo(){
        bar(); // OK : le compilateur connait bar()
    }
    Bref...

    Tout cela pour dire que tu peux, effectivement, envisager de ne pas fournir de prototype seul sur les fonctions inline, mais qu'il faudra alors �tre particuli�rement attentif � l'ordre dans lequel tu les �crit, surtout si l'une d'elle doit faire appel � une autre
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  4. #4
    Membre averti
    Inscrit en
    Mars 2013
    Messages
    31
    D�tails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 31
    Par d�faut
    Bonjour � vous deux et merci de vous attarder sur mon probl�me.

    Je pense que j'avais relativement bien compris ce que tu expliques Koala. Mais je n'arrive pas � comprendre ce qui se passe dans mon cas...

    Tu as raison Neckara, je vais mettre un peu de code pour expliquer mon probl�me. Je pensais que ma question �tait relativement g�n�rale pour ne pas avoir besoin de s'attarder sur mon cas, mais visiblement non

    Je vous propose donc deux fichiers: toto.cpp et toto.h

    toto.h contient plusieurs choses, dont la d�finition de la fonction inline qui m'int�resse:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // patati patata
     
    inline double carre(double a, double b)
    {
    return a*a+b*b; // J'ai écris n'importe quoi ici
    }
     
    // patati patata
    toto.cpp contient lui plusieurs d�finition de fonction dont une en particulier

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // patati patata
     
    void Truc(...)
    {
    double carre(double a, double b); //qui ressemble à un prototype (mais sans "inline")
    double h,f,g;
    // patati patata
    h=carre(f,g);
    // patati patata
     
    }
     
    // patati patata

    Avec ce code, �a ne fonctionne pas (ni m�me lorsque je rajoute "inline" dans le prototype de la fonction): "undefined reference to carre".

    Pour tester, j'ai simplement d�plac� le prototype de ma fonction (en ajoutant le mot cl� inline cette fois) juste au dessus de la d�finition de ma fonction inline dans le .h et non plus dans le .cpp comme c'�tait le cas avant.

    toto.h devient alors:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // patati patata
     
    inline double carre(double a, double b);
    inline double carre(double a, double b)
    {
    return a*a+b*b; // J'ai écris n'importe quoi ici
    }
     
    // patati patata
    Et l� suprise, �a fonctionne...
    Je ne comprend pas pourquoi. Autant je comprend l'utilit� d'un prototype quand il est possible que le compilateur rencontre l'appel � une fonction avant la d�claration de cette fonction.
    Mais avec les fonction inline, la d�claration est dans le .h. Quoiqu'il arrive, il va donc rencontrer la d�claration avant l'appel (dans mon cas en tout cas) et je ne vois donc pas l'utilit� de lui rajouter le prototype...

  5. #5
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Citation Envoy� par Josiane22 Voir le message
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // patati patata
     
    void Truc(...)
    {
    double carre(double a, double b); //qui ressemble à un prototype (mais sans "inline")
    double h,f,g;
    // patati patata
    h=carre(f,g);
    // patati patata
     
    }
     
    // patati patata
    Attention, ce code l� ne fait absolument pas ce que tu crois!!!

    Il d�clare une fonction nomm�e carre qui prend deux double comme param�tres et renvoyant un double...

    Si tu veux appeler ta fonction, il faut... d�clarer une variable qui sera initialis�e avec le retour de la fonction sous la forme de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    // patati patata
     
    void Truc(...)
    {
    double x/* ou truc, ou meme carre */ =carre(double a, double b); //qui ressemble à un prototype (mais sans "inline")
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  6. #6
    Membre averti
    Inscrit en
    Mars 2013
    Messages
    31
    D�tails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 31
    Par d�faut
    D�sol� mais je ne comprends pas ce que tu veux me dire...

    est bien remplac� par ce qu'il y a dans ma fonction inline non? Donc h vaut bien ensuite f*f+g*g?

    Pour ce qui est de la ligne
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    double carre(double a, double b);
    , on est d'accord que ce n'est que le prototype de la fonction inline non?

    PS: Je pr�cise que le probl�me que j'ai c'est lorsque je compile en mode DEBUG. Avec une compilation "normale", tout se passe bien...
    De plus, le probl�me survient � l'�dition de lien.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [POO] Prototypes de fonctions et IE
    Par T.NightGlow dans le forum Biblioth�ques & Frameworks
    R�ponses: 9
    Dernier message: 15/01/2008, 16h50
  2. Fonctions inline
    Par vdumont dans le forum C++
    R�ponses: 5
    Dernier message: 12/05/2006, 19h40
  3. .net prototype de fonction
    Par stgi02 dans le forum MFC
    R�ponses: 1
    Dernier message: 13/04/2006, 22h41
  4. prototype de fonction ?
    Par salseropom dans le forum C
    R�ponses: 3
    Dernier message: 07/04/2006, 10h01
  5. Fonctions inlines et fichiers .lib
    Par michhh dans le forum C++
    R�ponses: 3
    Dernier message: 05/07/2005, 03h09

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