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 :

[C++] Pourquoi et comment ce code fonctionne ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut [C++] Pourquoi et comment ce code fonctionne ?
    Bonjour,

    Quelqu'un peut il m'expliquer pourquoi ce code fonctionne ?

    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
    #include <iostream>
     
    class test
    {
    public:
        void hello();
    };
     
    void test::hello()
    {
        std::cout<<"hello"<<std::endl;
    }
     
     
    int main ()
    {
        test * ptr = NULL;
        ptr->hello();
        return 0;
    }
    J'ai bien un "hello" sur la console...

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    La fonction test::hello() n'accède à aucune donnée de l'objet test, donc un appel de cette fonction sur une instance invalide aura de fortes chances de fonctionner.

    Plus simplement, dis toi que le compilo va traduire ta fonction membre de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void test_hello(test* this)
    {
        std::cout<<"hello"<<std::endl;
    }
    test_hello(NULL);

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut .
    Je penssais à une chose dans le genre mais trop vraiment y croire. Du coup ma fonction hello n'est pas "crée" comme une fonction membre de ma classe, mais comme une bête fonction à la sauce C.

    Question supplementaire, pour eviter ce genre de comportement, le seul moyen est de faire appel à une donnée membre ?

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par chronos Voir le message
    Question supplementaire, pour eviter ce genre de comportement, le seul moyen est de faire appel à une donnée membre ?
    Ou de tester this
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(this == NULL)
    {
       ...
    }
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 228
    Par défaut
    Effectivement, cette solution me plait bien ^^

    Merci à vous

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ou rendre la fonction virtuelle...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par chronos Voir le message
    Je penssais à une chose dans le genre mais trop vraiment y croire. Du coup ma fonction hello n'est pas "crée" comme une fonction membre de ma classe, mais comme une bête fonction à la sauce C.
    Heu... non.... tu confonds tout là...

    Le code "machine" utilisé par le CPU n'a même pas la notion de "fonction".
    Pour le CPU, il n'y a pas de fonction membre / fonction pas membre / statique ou autre... juste de la mémoire et une pile d'execution.

    Quand à l'utilisation d'une donnée membre, aucune vérification ne sera faite non plus... le CPU va juste taper dans la mémoire autour de this (null) + offset... donc tu auras une exception genre: "illegal memory access to memory at 0x000000C"
    L'utilisation d'une fonction virtuelle sera pareil, puisque le CPU ira taper dans la donnée membre à l'offset 0 (la table virtuelle).

    Il n'y a pas moyen de se prémunir contre ce genre de mauvaise programmation hors du runtime, sauf à utiliser un vrai compilateur, qui va probablement te marquer le code ainsi écrit comme erreur (déréférencement de 'NULL'). En tout cas, VC9 me met une jolie erreur sur l'appel à Hello !

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En quoi l'appel d'une fonction non-virtuelle n'utilisant pas this est-il un déréférencement de pointeur nul ? Puisque le pointeur n'est justement pas déréférencé!

    Je suis étonné que VC9 mette une erreur pour un type C++ natif, alors que la bibliothèque MFC elle-même emploie ce genre de stratagème pour certaines fonctions:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    HWND CWnd::GetSafeHwnd()
    {
    	return (this==NULL ? NULL : this->m_hWnd);
    }
    PS: Est-ce une erreur d'éxécution ou de compilation ? Dans le cas d'une erreur d'exécution, se produit-elle aussi en mode Release ?

    Edit: Notez qu'en .Net, appeler une méthode, virtuelle ou non, causera une NullReferenceException si la référence .Net est nulle.
    http://blogs.msdn.com/oldnewthing/ar...6/4407029.aspx
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En quoi l'appel d'une fonction non-virtuelle n'utilisant pas this est-il un déréférencement de pointeur nul ? Puisque le pointeur n'est justement pas déréférencé!
    Jette un coup d'oeil à http://www.developpez.net/forums/d61...uter/pointeur/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 17/02/2011, 14h45
  2. [XMLHttpRequest] Pourquoi ce code fonctionne sous IE8 et pas sur Firexox 3.0.11
    Par homeostasie dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 23/07/2009, 14h50
  3. Réponses: 6
    Dernier message: 11/07/2007, 13h29
  4. Réponses: 6
    Dernier message: 12/04/2007, 13h58
  5. Réponses: 1
    Dernier message: 02/06/2005, 19h23

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