21916Fermer21918
squalylLe 28/11/2013 à 14:56
A la question "quelle est la différence entre un pointeur et un tableau en C", je peux apporter une réponse nouvelle:

Les différences qui existent entre les deux sont là EXCLUSIVEMENT pour faire chier les développeurs.

soit un code assez bidon

/*393*/ typedef struct test_s {
/*394*/ unsigned short field2;
/*395*/ unsigned char ftest[2];
/*396*/ unsigned char fnext;
/*397*/ } test_t;
/*398*/ test_t testdata;
/*399*/ unsigned char buf[47];
/*400*/ unsigned char *ptr;
/*401*/
/*402*/ unsigned short bugcon(void)
/*403*/ {
/*404*/ unsigned short value1;
/*405*/ unsigned short value2;
/*406*/ ptr = (unsigned char edata *) &buf;
/*407*/ value1 = testdata.ftest - (offsetof(test_t,ftest)+2) - ptr ;
/*408*/ value2 = testdata.ftest - ( (offsetof(test_t,ftest)+2) + ptr );
/*409*/ return value1-value2;
/*410*/ }

la fonction bugcon() ne renverra PAS ZERO sur tous les compilateurs.

Ca fait deux jours que suis dessus.

En fait, en C, tu n'as PAS le droit de calculer <ARRAYBASE> - <CONSTANT> (le bug est présent même sans offsetof), parce qu'en réalité, ça fait accéder à des offsets négatifs ce qui n'a pas de sens logique.

DONC OFFICIELLEMENT <ARRAYBASE> - <CONSTANT> est INDEFINI !

Alors que <POINTERCHAR> - constant fonctionne.


Par contre, la plupart des compilateurs normaux (MSVC, gcc, microchip) le tolèrent en considérant <ARRAYBASE> comme un pointeur.

MAIS PAS le compilateur particulier sur lequel je bosse, qui générait tout simplement du code invalide, sans warning!!

je n'ai pas parlé de pointeurs void ici, on travaille avec des unsigned char*.

Vous noterez au passage que les constructions suivantes sont valides

ARRAYBASE + CONSTANT (indexation)
ARRAYBASE + POINTER (cast auto)
ARRAYBASE - POINTER (idem)
ARRAYBASE - POINTER - CONSTANT
ARRAYBASE - ( CONSTANT + POINTER )

je me demande quand même à quel point c'est défini (oupa) par les standards C.