• [^] # Re: Petites precisions

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

    Je suis entièrement d'accord avec toi. Le principal reste cependant que le preproc puisse savoir a quoi il a à faire. Sinon ca part en vrille.

    i= (void *)0 // initialisation avec un pointeur (pour faire un reset :-))

    La le preprocesseur C t'enverra bouller. Il se dépechera de remplacer ton (void *)0 par une adresse particulière qui permettra au compilo de comprendre qu'il a à faire a un pointeur invalide. Généralement il faut passer par une autre macro.

    Au final tu as souvent un truc du genre
    {one pass preproc}
    (\*.*=) 0 -> %1 = &hFFFFFFFF (tout ce qui est de la forme *toto=0 devient *toto=&hFFFFFFFF ou &hFFFFFFFF est invalide)
    NULL -> &hFFFFFFFF
    (void\*)0 -> &hFFFFFFFF (tous les (void*)0 sont remplacés comme plus haut )
    ___reset -> &h00000000

    Bref les preprocesseurs essayent de se blinder contre les mecs qui rentrent la valeur 0 dans un pointeur et remplace avant compil tous les zéros rencontrés par une adresse invalide ou un jeu d'instruction pour que le compilo comprenne bien que ca n'est plus un pointeur.

    En bref si p est un pointeur
    p=0 sera remplacé de facon triviale par le préprocesseur et le pointeur p sera invalide.
    Derrière il sera impossible de faire un p++.

    De même si tu lis la norme posix, on a souvent :
    - return NULL if ....
    Mais pas
    - return 0 if ...


    Normalement avec la signature de la fonction on doit pouvoir s'en sortir. Si c'est un pointeur en retour alors 0=NULL, sinon c'est bien un 0 tout ce qu'il y a de plus standard.
    Bien sur si la fonction est bizaroide au point que l'on sait qu'elle retourne quelquechose mais que l'on ne sait pas si c'est un pointeur ou pas la on a un problème et le NULL est obligatoire. Mais il est théoriquement impssible de faire uen telle fonction.

    Dans les bonnes règles de programmation on rappèle toujours qu'il ne faut pas considérer qu'un pointeur est un entier.

    Faire ne serait-ce qu'une semaine d'assembleur permet de connaitre la différence pour toute la vie. Même si la mémoire est continue...

    Peut-être qu'un jour les compilateurs mettrons un gros warning lorsqu'un pointeur est initialisé avec un int.

    ben si tu fais
    int i=2;
    char *a=i;
    On peut remonter un warning (et c'est déjà le cas).

    Par contre si tu fais char *a=2 .... C'est valide et il faut que ca le reste, 2 est une adresse mémoire tout ce qu'il y a de plus valable.

    Ceci étant je suis également partisan du NULL en lieu et place du 0, mais c'est principalement pour la lisibilité. Quelqu'un qui veut utiliser des 0 a la place peut le faire si il est propre dans son code.

    Kha