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 :

cacher l'implémentation des fonctions inline


Sujet :

C++

  1. #21
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Merci beaucoup pour ta réponse mais il y a encore une nuance qui doit m'échapper car je ne comprends plus ce qui empêche de cacher l'implémentation de fonctions inline si on peut les définir dans un .cpp.
    Il faut une definition d'une fonction inline dans toute unite de compilation qui l'utilise. Donc la definition ne peut etre cachee que pour des fonctions qui ne sont pas utilisees par les clients.

  2. #22
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    D'accord. Donc, si j'ai bien compris, on peut finalement cacher une partie des implémentations en imbriquant des fonctions inline comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Foo 
    {
    public:int devoile(int);
    private:int cache(int);
    };
    inline int Foo::devoile(int i){return cache(i);} // ne peut pas être caché
    inline int Foo::cache(int i){return i;} // peut-être caché
    Le client verra effectivement l'implementation de "devoile" mais l'implémentation de "cache" pourra en revanche ne pas lui être montrée. Non?

  3. #23
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    D'accord. Donc, si j'ai bien compris, on peut finalement cacher une partie des implémentations en imbriquant des fonctions inline comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Foo 
    {
    public:int devoile(int);
    private:int cache(int);
    };
    inline int Foo::devoile(int i){return cache(i);} // ne peut pas être caché
    inline int Foo::cache(int i){return i;} // peut-être caché
    Le client verra effectivement l'implementation de "devoile" mais l'implémentation de "cache" pourra en revanche ne pas lui être montrée. Non?
    devoile utilise cache, donc si devoile est utilise, cache aussi et il faut voir l'implementation de cache comme elle est inline. Et si elle ne l'est pas, l'interet de devoile tel qu'ecrit est a priori faible.

  4. #24
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut
    Ce qu'il faut, c'est qu'une fonction inline soit definie (et de la meme maniere) dans toutes les unites de compilations qui l'utilisent. Le plus simple est de mettre la definition dans le .hpp qui la declare, mais ce n'est en rien obligatoire. Il est relativement courant quand on adopte l'organisation une classe=un .hpp et un .cpp de ne definir dans le .hpp que les fonctions inline publiques et protegees et definir dans le .cpp les fonctions inline privees qui ne sont pas utilisees par les fonctions inline presentes dans le .hpp.
    Mais si l'on veut permettre une utilisation des fonctions en ligne par les programmeurs client tout en leur cachant le code source de ces mêmes fonctions, comment peut-on s'y prendre ? Si la définition de la fonction inline doit être présente dans chaque unité de compilation on ne peut déclarer une fonction membre dans le fichier d'entête et fournir sa définition inline dans un fichier objet déjà compilé. Le résultat côté programme client sera forcément un appel de fonction. On est donc obligé de fournir le code des fonctions que l'on souhaite mettre en ligne. C'est cela qui me dérange...

    A moins (je ne sais pas si ça fonctionne...) de déclarer une extern class et de définir celle-ci dans un fichier objet. Est-ce que ce genre de "manipulation" est possible ?

  5. #25
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut
    Citation Envoyé par PyNub Voir le message
    A moins (je ne sais pas si ça fonctionne...) de déclarer une extern class et de définir celle-ci dans un fichier objet. Est-ce que ce genre de "manipulation" est possible ?
    Non ça ne fonctionne pas, évidemment.
    Je m'en doutais un peu ceci-dit.

  6. #26
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par PyNub Voir le message
    Mais si l'on veut permettre une utilisation des fonctions en ligne par les programmeurs client tout en leur cachant le code source de ces mêmes fonctions, comment peut-on s'y prendre ?
    On ne peut pas sauf à fournir les fichiers compilés avec une option du genre lto et donc à imposer aux clients cette option.

    En passant, les fonctions qui ont un intérêt à être inline sont souvent triviales, quel est l'intérêt de les cacher? Je comprends un peu mieux le problème pour les templates, où il n'y a pas non plus de solution dans le cadre du langage. Mais même alors, l'absence généralisée de solution en dehors me fait penser que ce n'est pas un trop gros problème en pratique. Si ce l'était, les compilateurs fourniraient quelque chose depuis longtemps (ça se fait bien dans d'autres domaines).

  7. #27
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut
    Comme j'ai dit que j'allais refaire un test, le voici :
    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
    // carchain.h : Header classe chaine de caractères
    #include <string.h>
    #include <iostream>
    #ifndef CARCHAIN_H
    #define CARCHAIN_H
    class CarChain{
      char* tab;
    public:
      CarChain(int a);
      void print();
      void load (char *);
    };
     
    inline CarChain::CarChain (int a){
      tab = new char[a];
      memset(tab,' ',a);
    }
     
    inline void CarChain::print(){
      std::cout << tab << std::endl;
    }
    #endif
    L'implémentation d'une fonction dans un fichier à part :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // carchain.cpp implémentation de Carchain::load
     
    #include "carchain.h"
    #include <string.h>
    #include <iostream>
    #ifdef line
    inline void CarChain::load (char * src){memcpy(tab,src,strlen(src));}
    #else
    void CarChain::load (char * src){memcpy(tab,src,strlen(src));}
    #endif
    Le programme principal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // exo7.cpp : fonction inline
     
    #include "carchain.h"
     
    int main(){
      CarChain test(54);
      test.load("test et retest");
      test.print();
      return 0;
    }
    Le résultat des deux compilations :
    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
    29
    30
    31
    32
    33
    34
    35
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> g++ -c carchain.cpp -Wall -Dline
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> ls -l
    total 20
    -rw-r--r-- 1 mikmak users  272 28 août  18:42 carchain.cpp
    -rw-r--r-- 1 mikmak users  381 28 août  18:43 carchain.h
    -rw-r--r-- 1 mikmak users 2168 28 août  18:45 carchain.o
    -rw-r--r-- 1 mikmak users  148 27 août  19:54 exo7.cpp
    -rw-r--r-- 1 mikmak users 3387 27 août  19:59 exo7.s
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> g++ -o exo7 exo7.cpp carchain.o -Wall -O1
    exo7.cpp: In function ‘int main()’:
    exo7.cpp:8:29: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    /tmp/ccrSTqNa.o: In function `main':
    exo7.cpp:(.text+0x49): undefined reference to `CarChain::load(char*)'
    collect2: ld returned 1 exit status
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> ls -l
    total 20
    -rw-r--r-- 1 mikmak users  272 28 août  18:42 carchain.cpp
    -rw-r--r-- 1 mikmak users  381 28 août  18:43 carchain.h
    -rw-r--r-- 1 mikmak users 2168 28 août  18:45 carchain.o
    -rw-r--r-- 1 mikmak users  148 27 août  19:54 exo7.cpp
    -rw-r--r-- 1 mikmak users 3387 27 août  19:59 exo7.s
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> g++ -c carchain.cpp -Wall
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> g++ -o exo7 exo7.cpp carchain.o -Wall -O1
    exo7.cpp: In function ‘int main()’:
    exo7.cpp:8:29: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> ls -l
    total 32
    -rw-r--r-- 1 mikmak users   272 28 août  18:42 carchain.cpp
    -rw-r--r-- 1 mikmak users   381 28 août  18:43 carchain.h
    -rw-r--r-- 1 mikmak users  2440 28 août  18:46 carchain.o
    -rwxr-xr-x 1 mikmak users 12211 28 août  18:46 exo7
    -rw-r--r-- 1 mikmak users   148 27 août  19:54 exo7.cpp
    -rw-r--r-- 1 mikmak users  3387 27 août  19:59 exo7.s
    mikmak@linux-uf9h:~/Devel/C++/eckel/p246/exo7> ./exo7
    test et retest

  8. #28
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    280
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 280
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    On ne peut pas sauf à fournir les fichiers compilés avec une option du genre lto et donc à imposer aux clients cette option.
    Qu'est ce une option lto ?

    En passant, les fonctions qui ont un intérêt à être inline sont souvent triviales, quel est l'intérêt de les cacher?
    Oui en effet, il s'agit la plupart du temps de fonction d'initialisation, restitution de données etc...
    Le seul intérêt de les cacher serait dans l'exemple du cheshire que j'ai donnée au début tiré de "penser en c++" de Bruce Eckel. Dans cet exemple les données mêmes de la classe sont cachées au programmeur client, celui-ci ne voit qu'un pointeur vers une structure dont les détails font partie du fichier d'implémentation. Ce qui nous oblige a renoncer aux fonctions inline même pour le constructeur d'une telle classe, puisque montrer la façon dont le constructeur s'y prend pour initialiser la structure dévoilerai en même temps l'organisation de la structure.

    Je comprends un peu mieux le problème pour les templates, où il n'y a pas non plus de solution dans le cadre du langage.
    Je n'en suis pas encore aux templates dans mon apprentissage, mais j'examinerai bientôt ce point.

    Mais même alors, l'absence généralisée de solution en dehors me fait penser que ce n'est pas un trop gros problème en pratique. Si ce l'était, les compilateurs fourniraient quelque chose depuis longtemps (ça se fait bien dans d'autres domaines).
    Oui c'est ce qui m'a fait croire au début qu'il existait peut-être une solution à ce problème. Comme tu l'as dit précédemment le fait que les fonction inline sont la plupart du temps triviales réduit d'autant son importance.

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

Discussions similaires

  1. Bonnes pratiques vis à vis des fonctions inline ?
    Par Kaluza dans le forum Débuter
    Réponses: 8
    Dernier message: 14/04/2011, 20h35
  2. [XQUERY] implémenter des fonctions
    Par fatjoe dans le forum XQUERY/SGBD
    Réponses: 3
    Dernier message: 14/04/2010, 12h57
  3. Réponses: 18
    Dernier message: 27/02/2009, 19h19
  4. Classe Java qui implémente des fonctions oracles
    Par kamacho25 dans le forum Outils
    Réponses: 0
    Dernier message: 28/09/2007, 14h46
  5. Implémentation des fonctions mathématiques
    Par mat.M dans le forum Mathématiques
    Réponses: 9
    Dernier message: 17/06/2002, 16h19

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