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

Langage C++ Discussion :

Affecter un pointeur à NULL en C++03


Sujet :

Langage C++

  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut Affecter un pointeur à NULL en C++03
    Hello,

    Voici un code :
    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
    #include <stdlib.h>
     
    class Page
    {
    };
     
    Page page;
    Page* nextPage = &page;
     
    int test()
    {
        if (nextPage != NULL)
        {
            nextPage = NULL;
        }
     
        return 0;
    }
    Je teste sous Windows avec un MinGW récent, ça compile nickel.

    Je cross-compile avec une toolchain GCC pour MCU Renesas, basée sur une version GCC 4.8 je crois, et j'obtiens l'erreur suivante sur l'affectation de nextPage à NULL :
    invalid conversion from 'void*' to '_Page*' [-fpermissive]
    Pouvez-vous me confirmer que le problème viendrait de la toolchain (et/ou de sa configuration) et non de mon code ?

    Normalement, tout le monde compile en C++98 ou 03.

    Merci d'avance !
    Bktero


    PS : j'ai réussi à faire compiler le code avec un reinterpret_cast<Page*>(NULL) au fait.

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    NULL doit valoir 0 en C++, surtout pas la valeur utilisé en C qui est (void*)0.
    Le #include <stdlib.h> est un include du langage C, c'est lui qui doit mettre la mauvaise valeur dans NULL.
    Il faut utiliser #include <cstblib> en C++, qui lui devrait avoir la bonne valeur pour NULL.

  3. #3
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour,

    Pour compléter ce que dit dalfab :
    • En C, NULL est une constante qui vaut 0 et qui est castée ou pas en (void*).
    • En C++03, NULL est une constante entière qui vaut 0.
    • En C++11, NULL est soit une constante entière qui vaut 0, soit nullptr.

    Sources :
    http://en.cppreference.com/w/c/types/NULL
    http://en.cppreference.com/w/cpp/types/NULL

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    J'ai reproduit le problème avec MinGW en commentant l'inclusion stdlib et en définissant moi-même NULL à 0, avec sous sans cast. Le problème doit bien venir de là. Je vais enquêter sur la configuration de la toolchain de cross-compilation.

    Les en-têtes <cstd***> ne sont-elles pas apparues avec C++11 ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Les entêtes du C <****.h> qui sont compatibles C++ s'utilisent sous le nom <c****>, avec quelques adaptations de compatibilité et les fonctions ****() deviennent std::****().
    C'était là avant C++11, je pense dès C++98.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    J'ai l'impression que ton compilateur est un peu étrange. Je n'ai jamais eu de problème de ce genre.
    Si c'est un souci de compilateur comme je le pense, perso j'opterais pour simplement ignorer ce warning sur ce compilateur (voire cette version du compilateur) avec ifdef et pragma adéquats.

    j'ai réussi à faire compiler le code avec un reinterpret_cast<Page*>(NULL) au fait.
    Oui mais tu ne veux pas vraiment utiliser cette écriture bien lourde à chaque fois, non ?
    A défaut, une fonction template ou macro qui le fait pour toi sinon.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Les entêtes du C <****.h> qui sont compatibles C++ s'utilisent sous le nom <c****>, avec quelques adaptations de compatibilité et les fonctions ****() deviennent std::****().
    C'était là avant C++11, je pense dès C++98.
    En cherchant sur internet, notamment grâce cette discussion stackoverflow, j'ai compris que :
    • à l'exception de cstdint, les autres en-têtes existent depuis C++98
    • dans les en-têtes <c***>, les éléments sont définis dans le namespace std, alors que dans <std***.h>, ils sont dans le namespace global.
    • il est possible que les en-têtes <c****> définissent aussi les mêmes éléments dans le namespace global (optionnel, en plus du namespace std qui est obligatoire)



    Citation Envoyé par Bousk Voir le message
    J'ai l'impression que ton compilateur est un peu étrange. Je n'ai jamais eu de problème de ce genre.
    Si c'est un souci de compilateur comme je le pense, perso j'opterais pour simplement ignorer ce warning sur ce compilateur (voire cette version du compilateur) avec ifdef et pragma adéquats.
    Le seul moyen de contourner -fpermissive est d'utiliser des #pragmas, il ne semble pas y avoir de -fno-permissive. Vu que le code incriminé est dans une bibliothèque, utilisées sur plusieurs compilateurs, ça m'arrange pas de le polluer.


    Citation Envoyé par Bousk Voir le message
    Oui mais tu ne veux pas vraiment utiliser cette écriture bien lourde à chaque fois, non ?
    A défaut, une fonction template ou macro qui le fait pour toi sinon.
    Tu m'as pris pour qui ?! Bien sûr que je ne veux pas faire ça !!!
    Pour la raison "bibliothèque" évoquée plus haut, je n'ai pas non plus envie de rajouter des templates ou des macros (j'avais d'ailleurs fait une macro avec ce reinterpret_cast )



    Au final, mon collègue a trouvé une solution : il a changé la lib C utilisée. Il est passé de "optimized" à "newlib" dans les options de l'IDE.

    Merci pour votre aide

  8. #8
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Point plus intéressant, depuis au moins C++03, les entêtes <bidule.h> sont dépréciés, et ne doivent pas être utilisés.
    Il me semble même que gcc (dans certaines de ses versions au moins) émêt un warning dédié (de même qu'avec <strstream>)

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Point plus intéressant, depuis au moins C++03, les entêtes <bidule.h> sont dépréciés, et ne doivent pas être utilisés.
    Je vois des choses un peu contradictoires à ce sujet... D'après cette page, http://en.cppreference.com/w/cpp/header, il semble que oui. Pourtant, je vois aussi que <cmath> est apparu en C++17 : http://en.cppreference.com/w/cpp/numeric/math/abs

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Ca n'est pas contradictoire, tu n'as pas bien lu
    ce qui est dit, c'est que depuis C++17, les fonctions *abs sont définies dans cmath, en plus de cstdlib.
    cmath en lui même existait déjà, mais ne contenait pas ces fonctions-ci.

    historiquement, abs était si utilisée qu'on a jugé bon de ne pas obliger les développeurs à inclure math.h pour l'obtenir.

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Ah c'est subtil ! Merci pour cette explication de texte !

    PS : message n°3333 !

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

Discussions similaires

  1. Affecter une valeur NULL à un paramètre d'un Query ?
    Par Targan dans le forum Débuter
    Réponses: 10
    Dernier message: 18/06/2009, 13h55
  2. Problème avec l'affectation d'un NULL à un pointeur
    Par reeda dans le forum Visual C++
    Réponses: 3
    Dernier message: 14/04/2008, 11h38
  3. [JUnit] Pointer null sur objet testé
    Par Mister Nono dans le forum Tests et Performance
    Réponses: 11
    Dernier message: 29/03/2007, 10h38
  4. Réponses: 5
    Dernier message: 13/12/2006, 13h34
  5. Affecter la valeur NULL à une cellule d'une table
    Par jacma dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 06/05/2005, 14h43

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