C'de Struct Uzantısı
Reklam tanımlı 2 yapı olduğunu varsayalım:
typedef struct {
T x;
T y;
} A;
typedef struct {
A a;
T z;
} B;
B yapısına bir göstericiyi A yapısına işaretçi olarak kabul edebilir miyim?
Pratikte bu güvenilir / standart / taşınabilir / derleyici değişmezdir:
B b = {{1,2},3};
A * a = &b;
print(a->x);
print(a->y);
Yanıtlar
C17 6.7.2.1 şunu belirtir (vurgu benim):
Bir yapı nesnesi içinde, bit alanı olmayan üyeler ve bit alanlarının bulunduğu birimler, bildirildikleri sırada artan adreslere sahiptir. Uygun şekilde dönüştürülmüş bir yapı nesnesine bir işaretçi, başlangıç üyesine (veya bu üye bir bit alanı ise, o zaman içinde bulunduğu birime) işaret eder ve bunun tersi de geçerlidir .
Bu, B bnesnenin işaretçisini ilk üyesinin türüne "uygun şekilde dönüştürmeniz" gerektiği anlamına gelir . Bu dönüşüm örtük olarak gerçekleşmez, bunu açık bir atama yoluyla yapmalısınız:
A * a = (A*)&b;
Bunu yapmak, yukarıda alıntılanan bölüme göre iyi tanımlanmış ve güvenlidir.
Benzer şekilde, derleyicinin bir gösterici Ave Btakma ad vermeyecek bir gösterici olduğunu varsaymasına izin verilmez . Etkili 6.5.7 türü kuralı ("kesin örtüşme") bu durum için bir istisna verir:
Bir nesnenin depolanan değerine yalnızca aşağıdaki türlerden birine sahip olan bir lvalue ifadesi tarafından erişilmesi gerekir:
...
- üyeleri arasında yukarıda belirtilen türlerden birini içeren bir toplu veya birleşim türü
Örneğin, optimizasyon sırasında, işlevi çağıran bir derleyicinin void func (B* b), extern A a;başka bir çeviri biriminde tanımlanan bir dış hat değişkeninin işlev tarafından değiştirilmediğini varsaymasına izin verilmez .