Voici mon code:
#include <string.h>
#include <stdio.h>
typedef char BUF[8];
typedef struct
{
BUF b[23];
} S;
S s;
int main()
{
int n;
memcpy(&s, "1234567812345678", 17);
n = strlen((char *)&s.b) / sizeof(BUF);
printf("%d\n", n);
n = strlen((char *)&s) / sizeof(BUF);
printf("%d\n", n);
}
Utiliser gcc 8.3.0 ou 8.2.1 avec n'importe quel niveau d'optimisation sauf -O0, cela sort 0 2quand je m'y attendais 2 2. Le compilateur a décidé que le strlenest limité à b[0]et ne peut donc jamais égaler ou dépasser la valeur divisée par.
Est-ce un bug dans mon code ou un bug dans le compilateur?
Ce n'est pas clairement énoncé dans la norme, mais je pensais que l'interprétation générale de la provenance du pointeur était que pour tout objet X, le code (char *)&Xdevrait générer un pointeur qui peut itérer sur l'ensemble de X- ce concept devrait tenir même s'il Xse trouve sous-tableaux comme structure interne.
(Question bonus, existe-t-il un indicateur gcc pour désactiver cette optimisation spécifique?)
2 2sous diverses options.
s.best limité, b[0]il est limité à 8 caractères, et donc deux options: (1) accès hors limite dans le cas où il y a 8 caractères non nuls, qui est UB, (2) il y a un caractère nul, dans lequel le len est inférieur à 8, donc la division par 8 donne zéro. Ainsi, la compilation du compilateur (1) + (2) peut utiliser l'UB pour donner le même résultat aux deux cas