2017-02-07 5 views
1

gcc (6.3.1 20170109) lors de la compilation du programme suivantPourquoi est-ce que je reçois un avertissement "type-punned" même en utilisant un "char *`?

#include <stdio.h> 

int main(int argc, const char *argv[]) { 
    unsigned char x[] = {0x66, 0x19}; 
    printf("%i\n", ((short *)((char *)&x[0]))[0]); 
    return 0; 
} 

génère comme avertissement:

pun.c: En fonction 'principale': pun.c: 5: 5: avertissement: pointeur de type punned déréférencement cassera des règles strictes-aliasing [-Wstrict-aliasing]

Il vaut mieux ne aliasing autorisé lors de l'utilisation char pointeurs?

Répondre

3

Voici ce que C11 (ou au moins le projet de libre N1570) a à dire au sujet aliasing:

Un objet doit avoir sa valeur stockée accessible uniquement par une expression lvalue qui est l'un des les types suivants:

  • un type compatible avec le type effective de l'objet,
  • une version qualifiée d'un type compatible avec le type effective de l'objet,
  • un type qui est la signature ou le type non signé correspondant au type effective de l'objet ,
  • un type qui est le type signé ou non signé correspondant à une version qualifiée du de l'objet de type efficace ,
  • un type agrégat ou union qui inclut l'un des types susmentionnés parmi ses membres (y compris, de manière récursive, un membre d'une sous-agrégation ou une union contenue), ou
  • un type de caractère.

Le type caractère exception signifie que vous pouvez accéder à tout type via un char* ou unsigned char*, mais cela ne signifie pas que vous pouvez accéder à un char* via tout type. short* ne répond pas aux autres critères répertoriés ici pour char*, donc cette utilisation est un comportement indéfini.

De plus, vous pourriez casser les exigences d'alignement si cela était permis sans condition:

short x[] = {1, 2}; 
char* alias = x; 
printf("%i\n", *(short*)&alias[1]);