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
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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 éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 565
    Points : 7 648
    Points
    7 648
    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
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 109
    Points
    6 109
    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
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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 éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 565
    Points : 7 648
    Points
    7 648
    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 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    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
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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 sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    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>)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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 sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 189
    Points : 17 141
    Points
    17 141
    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.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    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