następującego kodu:Casting stałe do unii
#include <stdio.h>
typedef union {
int n;
char *s;
} val_t;
int main(void) {
val_t v1,v2;
v1 = (val_t)"Hello World";
v2 = (val_t)10;
printf("%s %d\n", v1.s, v2.n);
return(1);
}
kompiluje i wykonuje poprawnie z GCC. Jeśli spróbujesz rzucić stałą, dla której nie ma odpowiedniego pola w złączu, zostanie wygenerowany komunikat błędu.
Jednak patrząc na standard (C99), nie udało mi się zlokalizować sekcji, w której opisano to zachowanie. Stąd moje pytanie:
Czy C średnia gwarancji, że mogę rzucić stały się do rodzaju związków, pod warunkiem, że typ unia ma pole o typie zgodnym?
lub, innymi słowy:
Czy
((val_t)10)
ważny RValue typuval_t
?
Byłoby również interesujące wiedzieć, czy to zachowanie jest obsługiwane przez inne kompilatory (lub przynajmniej MS Visual C++). Czy ktoś wie?
EDYTOWANIE: Odlewanie do złącza jest rozszerzeniem GCC, więc nie jest dobrym pomysłem jego użycie.
Podziękowania dla Mauritsa i Neila! Nie myślałem o używaniu -pedantic do sprawdzenia!
Oprócz tego, że wygląda to na bardzo złe praktyki programistyczne, jest to interesujące pytanie. Pomyślałem, że po 20 latach programowania w C widziałem już wszystko, Najwyraźniej nie :) –
@MauritsRijk To naprawdę świetny sposób na implementację generycznych pojemników w C. Tworzysz klucz do kontenera typu unii z polami takimi jak int , wskaźnik podwójny i nieważny, a funkcja porównawcza, którą przekazujesz, wie, jakiego typu potrzebuje i uzyskuje dostęp do odpowiedniego członka związku. Właściwie nie rozumiem, dlaczego nie jest to standardowa część języka, ponieważ sposób zdefiniowania związków w K & R, każdy członek jest wyrównany do najniższego adresu, związek ma zagwarantowane właściwe wyrównanie pamięci dla wszystkich jego członków, i wystarczająco szeroki, aby pomieścić najszerszy. –