Sendikaları daha önce rahatça kullandım; Ben okuduğumda bugün alarma edildi bu yazı ve bu kodun bilmek geldi
union ARGB
{
uint32_t colour;
struct componentsTag
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} components;
} pixel;
pixel.colour = 0xff040201; // ARGB::colour is the active member from now on
// somewhere down the line, without any edit to pixel
if(pixel.components.a) // accessing the non-active member ARGB::components
aslında tanımlanmamış bir davranıştır. Sendikaların amaçlanan kullanımı bu değilse, nedir? Bazıları bunu ayrıntılı olarak açıklayabilir mi?
Güncelleme:
Birkaç şeyi açıklığa kavuşturmak istedim.
- Sorunun cevabı C ve C ++ için aynı değildir; cahil genç ben onu hem C hem de C ++ olarak etiketledi.
- C ++ 11'in standardını inceledikten sonra, aktif olmayan bir sendika üyesine erişmenin / denetlemenin tanımsız / belirtilmemiş / uygulama tanımlı olduğunu kesin olarak söyleyemedim. Bütün bulabildiğim §9.5 / 1 idi:
Standart mizanpaj birliği, ortak bir başlangıç sırasını paylaşan birkaç standart mizanpaj yapısı içeriyorsa ve bu standart mizanpajlı birleştirme türündeki bir nesne, standart mizanpaj yapılarından birini içeriyorsa, herhangi birinin ortak başlangıç sırasının incelenmesine izin verilir standart yapı yapı üyelerinden oluşur. §9.2 / 19: Karşılık gelen üyelerin mizanpaj türlerine sahip olması ve her iki üyenin bir bit alanı olmaması veya her ikisinin de bir veya daha fazla başlangıç sekansı için aynı genişliğe sahip bit alanları olması durumunda, iki standart yerleşim yapısı ortak bir başlangıç sırasını paylaşır üyeler.
- C'deyken ( C99 TC3 - DR 283 sonrası) bunu yapmak yasaldır ( Pascal Cuoq'a bunu getirdiği için teşekkürler ). Bununla birlikte, okunan değer okunduğu tür için geçersiz ("tuzak gösterimi" olarak adlandırılır) olursa, bunu yapmaya çalışmak tanımsız davranışlara yol açabilir . Aksi takdirde, okunan değer uygulama tarafından tanımlanır.
C89 / 90 bunu belirtilmemiş davranışlar altında ifade etti (Ek J) ve K & R'nin kitabı uygulamanın tanımlandığını söylüyor. K&R'den Alıntı:
Birliğin amacı budur - çeşitli türlerden herhangi birini meşru bir şekilde tutabilen tek bir değişken. [...] kullanım tutarlı olduğu sürece: alınan tür en son kaydedilen tür olmalıdır. Şu anda bir sendikada hangi türün depolandığını takip etmek programcının sorumluluğundadır; bir şey bir tür olarak saklanır ve başka bir tür olarak çıkarılırsa sonuçlar uygulamaya bağlıdır.
Stroustrup'un TC ++ PL'sinden alıntı (vurgu mayını)
Sendikaların kullanımı bazen "tip dönüşümü " için yanlış kullanılan verilerin [...] uyumluluğunda gerekli olabilir .
Her şeyden önce, bu soru (sorumu sorandan beri değişmeden kalan) sendikaların amacını anlamak niyetinde ve standardın neye izin verdiğine değil, örneğin kodun yeniden kullanımı için mirasın kullanılmasına elbette C ++ standardı tarafından izin verildiğini, ancak mirasın C ++ dil özelliği olarak kullanılmasının amacı ya da orijinal amacı değildi . Andrey'nin cevabı kabul edilen cevap olarak kalmaya devam etmesinin nedeni budur.
scouring C++11's standard I couldn't conclusively say that it calls out accessing/inspecting a non-active union member is undefined [...] All I could find was §9.5/1
...Gerçekten mi? paragrafın başındaki ana noktayı değil , bir istisna notu belirtirsiniz : "Bir birliktelikte, statik olmayan veri üyelerinden en fazla biri herhangi bir zamanda etkin olabilir, yani en fazla statik olmayan veri üyeleri herhangi bir zamanda bir birlik içinde saklanabilir. " - ve p4'e kadar: "Genel olarak, bir sendikanın aktif üyesini değiştirmek için açık yıkıcı çağrıları kullanmalı ve yeni operatörler yerleştirilmelidir "
b, g, r,
vea
bitişik olmayabilir ve bu nedenle bir düzenini eşleşmeyenuint32_t
. Bu, başkalarının belirttiği Endianess sorunlarına ek olarak.