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 :

NULL automatiquement définit ?


Sujet :

C

  1. #1
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut NULL automatiquement définit ?
    Bonjour,

    Je viens de m'apercevoir que la macroconstante NULL n'était pas définit dans le fichier <stdio.h>. Elle l'est dans stdlib.h, string.h etc...

    Pourtant, le programme suivant compile bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
     
    int
    main ()
    {
    	char *s = NULL;
    	printf("NULL = %p\n", NULL);
    	return 0;
    }
    Est ce que le compilateur (gcc dans mon cas), inclut automatiquement stdlib afin de définir NULL ?

    Ce n'est pas une question cruciale, mais j'aimerai comprendre pourquoi NULL est définit alors qu'elle n'a aucune raison de l'être.

    Merci d'avance

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Par défaut
    salut,

    NULL est defini dans stddef.h sous Linux. ce fichier est inclu par de nombreux .h presents dans /usr/include (y compris stdio.h). il est donc logique que NULL soit defini meme lorsque tu n'inclus que stdio.h (ca marche sous Linux, mais pas forcement partout ailleurs.. il vaut mieux inclure stdlib.h si tu veux etre sur que NULL sera defini).

    -pirus.

  3. #3
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Merci

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par _kal_
    Je viens de m'apercevoir que la macroconstante NULL n'était pas définit dans le fichier <stdio.h>. Elle l'est dans stdlib.h, string.h etc...

    Pourtant, le programme suivant compile bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
     
    int
    main ()
    {
    	char *s = NULL;
    	printf("NULL = %p\n", NULL);
    	return 0;
    }
    Est ce que le compilateur (gcc dans mon cas), inclut automatiquement stdlib afin de définir NULL ?

    Ce n'est pas une question cruciale, mais j'aimerai comprendre pourquoi NULL est définit alors qu'elle n'a aucune raison de l'être.
    Elle est définie dans <stddef.h> qui est généralement inclus dans <stdio.h>, <stdlib.h> etc. Mais à ma connaissance, ce n'est pas une obligation.

  5. #5
    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 Emmanuel Delahaye
    Elle est définie dans <stddef.h> qui est généralement inclus dans <stdio.h>, <stdlib.h> etc. Mais à ma connaissance, ce n'est pas une obligation.
    Pour autant que je m'en souvienne -- j'ai rapidement cherché la référence dans C90 et ne l'ai pas trouvée --, en C (contrairement au C++), les en-têtes standards ne peuvent pas s'inclure l'un l'autre. Donc, en en incluant un, on ne devrait avoir que les définitions de cet en-tête.

    Mais il y a un certains nombres d'indentificateurs qui doivent être définis par plusieurs en-têtes. NULL en fait partie et doit être défini par <stddef.h>, <stdio.h>, <stdlib.h> et j'en passe vraissemblablement (l'index de la norme ne fonctionne pas dans ce sens et ne pointe que vers la définition de <stddef.h>). size_t est un autre identificateur fourni par plusieurs en-têtes.

    J'ai vérifié sur Linux, inclure <stdio.h> ne fournit pas toutes les définitions de <stddef.h>.

  6. #6
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    C'est étrange, voici une parti (le début) du fichier stdio.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #if !defined __need_FILE && !defined __need___FILE
    # define _STDIO_H       1
    # include <features.h>
    
    __BEGIN_DECLS
    
    # define __need_size_t
    # define __need_NULL
    # include <stddef.h>
    
    # include <bits/types.h>
    # define __need_FILE
    # define __need___FILE
    #endif /* Don't need FILE.  *
    Donc soit il inclut stddef.h, soit il ne l'inclut pas. Mais pas en partie. Ou alors, peut-être qu'il redéfinit des macro de stddef.h s'il ne l'inclut pas.

    Si je n'inclus pas stdio.h, alors il y a une erreur de non reconaissance du symbole NULL. Par contre, printf peut quand même être utilisé en la typant implicitement en int. Est ce que l'éditeur de lien inclut par défaut les fonctions de la librairie standard ?

  7. #7
    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 _kal_
    C'est étrange, voici une parti (le début) du fichier stdio.h :

    Donc soit il inclut stddef.h, soit il ne l'inclut pas. Mais pas en partie. Ou alors, peut-être qu'il redéfini des macro de stddef.h s'il ne l'inclut pas.
    Je me fous des astuces d'implémentation. Inclure <stdio.h> ne fournit pas toutes les définitions de <stddef.h> mais seulement celles demandées par la norme. Que ce soit fait en recopiant les définitions, en incluant <stddef.h> après avoir joué avec des macros -- ce qui a l'air d'être le cas -- ou en incluant un autre en-tête qui est aussi inclus par <stddef.h> -- ce qui serait la première technique à laquelle j'aurais pensé -- ça ne me concerne pas.

    Si je n'inclus pas stdio.h, alors il y a une erreur de non reconaissance du symbole NULL.
    Sauf si tu as inclus <stddef.h>, <stdlib.h> ou un des autres en-têtes fournissant la définission. C'est normal.

    Est ce que l'éditeur de lien inclut par défaut les fonctions de la librairie standard?
    Non, mais gcc quand il appelle l'éditeur de liens, oui.

  8. #8
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Je me fous des astuces d'implémentation. Inclure <stdio.h> ne fournit pas toutes les définitions de <stddef.h> mais seulement celles demandées par la norme. Que ce soit fait en recopiant les définitions, en incluant <stddef.h> après avoir joué avec des macros -- ce qui a l'air d'être le cas -- ou en incluant un autre en-tête qui est aussi inclus par <stddef.h> -- ce qui serait la première technique à laquelle j'aurais pensé -- ça ne me concerne pas.
    Exact, je viens de tester avec la fonction offsetof censée être définit dans <stddef.h> sans inclure ce dernier et la compilation plante. Je ne comprend pas comment <stdio.h> peut inclure juste ce dont il a besoin dans <stddef.h> vu qu'il fait un include de celui-ci, mais bon soit!
    Le principal à retenir est que <stdio.h> inclut les définitions demandées par la norme.

    Citation Envoyé par Jean-Marc.Bourguet
    Non, mais gcc quand il appelle l'éditeur de liens, oui.
    C'est donc une particularité de gcc ? (je n'ai jamais testé d'autre compilo).

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par _kal_
    C'est donc une particularité de gcc ? (je n'ai jamais testé d'autre compilo).
    La plupart des éditeurs de liens ajoutent automatiquement la bibliothèque standard (le plus souvent, en excluant la partie 'flottante' pour éviter la surcharge des petits programmes...). Mais il y a des options pour ne pas l'ajouter, en ajouter une autre etc.

  10. #10
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Ok

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par _kal_
    C'est donc une particularité de gcc ? (je n'ai jamais testé d'autre compilo).
    La plupart des éditeurs de liens ajoutent automatiquement la bibliothèque standard (le plus souvent, en excluant la partie 'flottante' pour éviter la surcharge des petits programmes...). Mais il y a des options pour ne pas l'ajouter, en ajouter une autre etc.
    que ceux qui le savent deja me pardonnent de relever un point evident, mais l'editeur de liens n'a rien a voir avec la definition des macros..

    NULL, comme offsetof sont des macros, elles sont evaluees par le preprocesseur avant la compilation et - litteralement - n'existent plus ensuite; ce ne sont pas des symboles (qui sont resolus par l'editeur de liens apres la compilation).

    comme le fait remarquer Jean-Marc, le detail precis des operations mises en oeuvre pour inclure tout ou partie des declarations entre les differents fichiers .h n'est pas d'une grande importance pour le developpeur. ces manipulations varient d'ailleurs entre les compilateurs (icc vs. gcc), voire entre plusieurs versions successives d'un meme compilateur et des librairies systeme (qui fournissent les .h), et bien sur entre les OS (GNU/Linux vs. BSD).

    sans vouloir porter de jugement hatif, cette logique est d'ailleurs generalement plus difficile a suivre sous Linux qu'ailleurs (un fait qu'on peut sans doute attribuer a une certaine ambition d'universalite).

    -pirus.

  12. #12
    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 _kal_
    Exact, je viens de tester avec la fonction offsetof censée être définit dans <stddef.h> sans inclure ce dernier et la compilation plante. Je ne comprend pas comment <stdio.h> peut inclure juste ce dont il a besoin dans <stddef.h> vu qu'il fait un include de celui-ci, mais bon soit!
    A voir ce que tu as cité, stdio.h fait des choses particulières si on a définit __need_FILE. Ca ne m'étonnerait pas que stddef.h fait aussi des choses particulières si on a définit __need_NULL.

    C'est donc une particularité de gcc ? (je n'ai jamais testé d'autre compilo).
    Non. Tous les compilateurs que je connais passent les bibliothèques de leur langage quand ils appellent l'éditeur de liens. Mais on peut parfois jouer avec les options pour qu'ils ne le fassent pas.

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par pirus
    que ceux qui le savent deja me pardonnent de relever un point evident, mais l'editeur de liens n'a rien a voir avec la definition des macros..
    Certes, mais la réponse concernait une question directe sur les bibliothèque et non sur les macros. Bien lire tout le thread avant de répondre ou de commenter...

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Par défaut
    Effectivement, il etait question de printf(). my mistake..

    -pirus.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/11/2014, 16h01
  2. [PHP 5.2] définition automatique des paramètres de connexions
    Par van-bom dans le forum Langage
    Réponses: 3
    Dernier message: 26/04/2013, 21h37
  3. Réponses: 2
    Dernier message: 06/12/2012, 11h54
  4. Réponses: 1
    Dernier message: 26/10/2010, 15h25

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