Ekstensi Struct di C
Misalkan ada 2 struktur yang ditentukan iklan seperti:
typedef struct {
T x;
T y;
} A;
typedef struct {
A a;
T z;
} B;
Dapatkah saya memperlakukan penunjuk ke struktur B sebagai penunjuk ke struktur A?
Dalam praktiknya, dapat diandalkan / standar / portabel / compiler-invariant:
B b = {{1,2},3};
A * a = &b;
print(a->x);
print(a->y);
Jawaban
C17 6.7.2.1 menyatakan ini (penekanan saya):
Dalam objek struktur, anggota bidang non-bit dan unit di mana bidang bit berada memiliki alamat yang meningkat dalam urutan deklarasinya. Sebuah pointer ke objek struktur, yang diubah sesuai, menunjuk ke anggota awalnya (atau jika anggota itu adalah bit-field, maka ke unit tempatnya berada), dan sebaliknya .
Ini berarti bahwa Anda harus "mengubah" pointer untuk B b
objek tersebut menjadi tipe anggota pertamanya. Konversi ini tidak terjadi secara implisit, Anda harus melakukan ini dengan cast eksplisit:
A * a = (A*)&b;
Melakukannya didefinisikan dengan baik dan aman, sesuai dengan bagian yang dikutip di atas.
Demikian pula, kompilator tidak diperbolehkan berasumsi bahwa pointer ke A
dan pointer B
tidak alias. Aturan tipe efektif 6.5.7 ("aliasing ketat") memberikan pengecualian untuk kasus ini:
Sebuah objek harus memiliki nilai tersimpan yang diakses hanya dengan ekspresi lvalue yang memiliki salah satu dari tipe berikut:
...
- jenis agregat atau gabungan yang mencakup salah satu jenis yang disebutkan di atas di antara anggotanya
Misalnya, selama pengoptimalan, compiler yang memanggil fungsi void func (B* b)
tersebut tidak diizinkan untuk mengasumsikan bahwa variabel linage eksternal yang extern A a;
ditentukan di beberapa unit terjemahan lain tidak diubah oleh fungsi tersebut.