Union (uniegroep) is een speciaal datatype dat verschillende waarden in hetzelfde geheugen opslaat. In een union bevinden alle leden zich op hetzelfde geheugenadres, en de hoeveelheid geheugen is gelijk aan de grootte van het grootste lid.
Gebruik:
Voorbeeld:
union Data { int i; float f; char s[4]; }; union Data d; d.i = 0x41424344; // nu zijn er 4 bytes in het geheugen, die als int, float of string gelezen kunnen worden printf("%c%c%c ", d.s[0], d.s[1], d.s[2]); // vendor-specifieke output
Valkuilen en gebruiksregels:
Vraag: Wat is de zin van het gebruik van een union, wanneer je gewoon een structuur met meerdere velden kunt gebruiken?
Antwoord: Het gebruik van een union bespaart geheugen, omdat op elk moment slechts ÉÉN waarde intern wordt opgeslagen, en niet allemaal tegelijk. In een structuur wordt geheugen voor elk veld toegewezen, terwijl in een union alleen voor het grootste veld geheugen wordt gereserveerd, de andere "delen" dit geheugen. Bovendien stelt een union je in staat om veilige of opzettelijke omzettingen tussen verschillende datatypes in hetzelfde geheugensegment uit te voeren.
Voorbeeld:
struct S { int i; float f; } s; // sizeof = sizeof(int) + sizeof(float) union U { int i; float f; } u; // sizeof = max(sizeof(int),sizeof(float))
Verhaal
In een apparaatdriverproject werd de verbinding met de hardware via een union met bit-toegang tot gegevens gedaan. Na een kleine refactor begon de ontwikkelaar in een verkeerd union-veld te schrijven, wat leidde tot het lezen van verouderde gegevens en fatale systeemfouten, omdat in de union op elk moment slechts één veld "actueel" is.
Verhaal
Bij het uitwisselen van netwerkpakketten via een union voor geheugensynchronisatie vergat de ontwikkelaar de structurering van de structuren in overweging te nemen. Dit resulteerde in een verschuiving van één byte, en de struct werd met onjuiste offsetten geparsed, wat het protocol incompatibel maakte met het origineel.
Verhaal
Bij het werken aan een serialisatiebibliotheek droeg de programmeur de union als waarde over naar een functie, waar het benodigde veld niet werd geïnitialiseerd voordat het werd gelezen. Dit leidde tot onjuiste serialisatie van de gegevens, wat resulteerde in rommel in de uitvoerstream en het onmogelijk maken om de oorspronkelijke informatie te herstellen.