• [^] # Re: Petites precisions

    Posté par . En réponse au journal J'adore Linus. Évalué à 0.

    > > static char* p ;
    > p est un null pointer

    Non, c'est initialisé à 0. C'est le chargeur qui fait ça. C'est peut-être pas dans la norme mais c'est comme ça. Le chargeur ne s'occupe pas de savoir si c'est une zone qui stocke des pointeurs ou des int, etc... Le chargeur voit une grosse zone (pour toutes les variables statiques) et met tout à 0.

    Si tu as la norme sous main, copie ici comment est initialisé une zone static (C'est aussi pour mon information car je n'ai pas la norme, btw, si tu as un pointeur sur la norme, je suis preneur).

    > > void * p = (void *)(p1 - p2) ;
    > 0 pour p

    Pourtant tu dis : '0' même signification que '(void *)0' même signification que null pointeur. Or ici j'ai bien '(void *)0' (c-à-d null pointeur) et tu dis que c'est 0. Pas claire.

    > ça n'a pas de sens, NULL est une macro

    Remplace NULL par "null pointer" si tu veux.

    > 100%
    Non. pour varargs, ça ne marche pas.
    Heureusement, gcc a la délicatesse de le dire :
    printf("%p\n", 0) ;
    test.c:3: attention : l'argument de format n'est pas un pointeur (arg 2)
    avec :
    fprintf("%p\n", NULL) ;
    Pas de warning, c'est correct.

    Avec c++ ça ne marche pas avec la surcharge. 0 reste un int. (void*)0 est un pointeur et NULL est null pointeur (implémentation dépendant de la plate forme).

    Exemple :
    test.c
    #include <stdio.h>
    void f(int i) {
    printf("f(int)\n") ;
    }
    void f(void *s) {
    printf("f(void *)\n") ;
    }
    void f(char *s) {
    printf("f(char *)\n") ;
    }
    void f(long u) {
    printf("f(long)\n") ;
    }
    int main(void) {
    f(0) ;
    f((void*)0) ;
    f((char*)0) ;
    f(0L) ;
    f(NULL) ;
    return 0 ;
    }


    g++ -Wall test.c
    test.c: Dans function « int main() »:
    test.c:15: attention : passing NULL used for non-pointer converting 1 of `void f(int)'

    NULL est remplacé par __null qui est un mot clé de g++.
    Mais d'autres implémentations ont un truc du style :
    # ifdef __cplusplus
    # define NULL (0L)
    # else
    # define NULL ((void*) 0)
    # endif


    Exécution :
    ./a.out
    f(int)
    f(void *)
    f(char *)
    f(long)
    f(int)


    Donc ce n'est pas la même chose et surtout pas à 100 %.