Ini kode saya:
#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);
}
Menggunakan gcc 8.3.0 atau 8.2.1 dengan level optimasi apa pun kecuali -O0
, ini akan keluar 0 2
ketika saya mengharapkan 2 2
. Kompilator memutuskan bahwa strlen
terikat b[0]
dan karenanya tidak pernah sama atau melebihi nilai yang dibagi.
Apakah ini bug di kode saya atau bug di compiler?
Ini tidak dijabarkan dalam standar dengan jelas, tetapi saya pikir interpretasi arus utama dari sumber pointer adalah bahwa untuk objek apa pun X
, kode tersebut (char *)&X
harus menghasilkan pointer yang dapat beralih ke seluruh X
- konsep ini harus berlaku bahkan jika X
kebetulan memiliki sub-array sebagai struktur internal.
(Pertanyaan bonus, apakah ada tanda gcc untuk mematikan pengoptimalan khusus ini?)
2 2
bawah berbagai opsi.
s.b
terbatas untuk b[0]
itu terbatas pada 8 karakter, dan karenanya dua opsi: (1) akses keluar jika ada 8 karakter non-nol, yaitu UB, (2) ada karakter nol, di mana len kurang dari 8, maka membaginya dengan 8 memberi nol. Jadi menyusun (1) + (2) kompiler dapat menggunakan UB untuk memberikan hasil yang sama untuk kedua kasus