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 2
cuando esperaba2 2
. El compilador decidió que strlen
está 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 *)&X
debería generar un puntero que pueda iterar sobre el todo X
: este concepto debería mantenerse incluso si X
sucede que tiene sub-matrices como estructura interna.
(Pregunta adicional, ¿hay una bandera gcc para desactivar esta optimización específica?)
2 2
bajo varias opciones.
s.b
se 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