Oto mój kod:
#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);
}
Używanie gcc 8.3.0 lub 8.2.1 z dowolnym poziomem optymalizacji, z wyjątkiem -O0tych wyników, 0 2gdy się spodziewałem 2 2. Kompilator zdecydował, że strlenjest on ograniczony b[0]i dlatego nigdy nie może być równy ani przekraczać dzielonej wartości.
Czy to błąd w moim kodzie czy błąd w kompilatorze?
Nie jest to wyraźnie określone w standardzie, ale myślałem, że głównym interpretacją pochodzenia wskaźnika jest to, że dla każdego obiektu Xkod (char *)&Xpowinien generować wskaźnik, który może się iterować w całym X- ta koncepcja powinna obowiązywać, nawet jeśli Xzdarzy się, że ma pod-tablice jako struktura wewnętrzna.
(Pytanie dodatkowe, czy istnieje flaga gcc, która wyłącza tę konkretną optymalizację?)
2 2w różnych opcjach.
s.bjest ograniczony do b[0]tego, jest ograniczony do 8 znaków, a zatem dwie opcje: (1) dostęp poza granicami, w przypadku gdy istnieje 8 znaków innych niż null, czyli UB, (2) występuje znak null, w którym długość jest mniejsza niż 8, a zatem podzielenie przez 8 daje zero. Tak więc zestawienie kompilatora (1) + (2) może użyć UB, aby dać ten sam wynik w obu przypadkach