Aquí está mi código:
#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);
}
Usando gcc 8.3.0 u 8.2.1 con cualquier nivel de optimización, excepto -O0, esto sale 0 2cuando esperaba2 2 . El compilador decidió que strlenestá limitado b[0]y, por lo tanto, nunca puede igualar o superar el valor dividido por
¿Es esto un error en mi código o un error en el compilador?
Esto no se explica claramente en el estándar, pero pensé que la interpretación principal de la procedencia del puntero era que para cualquier objeto X, el código (char *)&Xdebería generar un puntero que pueda iterar sobre el todo X: este concepto debería mantenerse incluso si Xsucede que tiene sub-matrices como estructura interna.
(Pregunta adicional, ¿hay una bandera gcc para desactivar esta optimización específica?)
2 2bajo varias opciones.
s.bse limita a b[0]que se limita a 8 caracteres, y por lo tanto dos opciones: (1) fuera de límite de acceso en caso de que haya 8 caracteres que no son nulos, lo cual es UB, (2) hay un carácter nulo, en cuyo la len es menor que 8, por lo tanto, dividir por 8 da cero. Entonces