Problème d’expression de la déclaration GCC

Je viens de lire sur Statement Expressions Extension dans GCC et j’ai constaté un comportement inattendu lors de son utilisation.

Veuillez observer cet exemple:

#include  int main(void) { char* res1 = ({ char arr[] ={'h', 'e', '\0'}; // was char *arr[] arr[0] = 'x'; char* ptr = arr; ptr; }); char* res2 = ({ char arr[] ={'h', 'e', '\0'}; // was char *arr[] arr[0] = 'X'; char* ptr = arr; ptr; }); printf ("%s %p\n", res1, res1); printf ("%s %p\n", res2, res2); return 0; } 

Sortie:

 X 0x7fff93098160 X 0x7fff93098160 

Je remarque que les variables arr dans le premier bloc et arr dans le second bloc prennent la même adresse mémoire.

Pourquoi ça arrive ??

Les deux occurrences de arr sont des objects de tableau avec une durée de stockage automatique; ils sont locaux au bloc englobant { ... } dans l’expression de l’instruction.

Chaque expression d’instruction saisit l’adresse de cette variable locale; cette adresse est enregistrée dans res1 et res2 and used *after* the end of the block, when the object arr` n’existe plus .

C’est le même problème qu’une fonction renvoyant l’adresse d’une variable locale. L’adresse devient invalide lorsque la variable cesse d’exister et que le comportement du programme n’est pas défini.

Alors ne fais pas ça.

Autant que je sache, la scope des variables définies dans les expressions de déclaration ne concerne que les expressions de déclaration elles-mêmes. En d’autres res1 , lorsque res1 est initialisé, le tableau est déjà hors de scope et le pointeur pointe vers la mémoire non allouée. Le tableau dans la deuxième expression de la déclaration occupe la même mémoire. Ce n’est en fait pas très différent du code suivant:

 char* res1; { char arr[] ={'h', 'e', '\0'}; arr[0] = 'x'; char* ptr = arr; res1 = ptr; } char* res2; { char arr[] ={'h', 'e', '\0'}; arr[0] = 'X'; char* ptr = arr; res2 = ptr; } printf ("%s %p\n", res1, res1); printf ("%s %p\n", res2, res2); 

Les deux tableaux sont locaux aux expressions de l’instruction et la mémoire qu’ils occupent peut être réutilisée après la fin de l’expression. Dans ce cas, il est réutilisé.

Si vous souhaitiez accéder aux valeurs de ce pointeur ou les utiliser, vous invoqueriez un comportement indéfini. Par conséquent, leur égalité est sans conséquence.