2010-01-27 16 views
14

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 typu val_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!

+1

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 :) –

+1

@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. –

Odpowiedz

5

W GNU C language extensions odlewanie do zwoju jest oznaczone jako rozszerzenie standardu C. Najprawdopodobniej nie znajdziesz go w C99 lub innym standardzie C. Kompilator IBM C obsługuje również to rozszerzenie.

5
[[email protected] NeilB]$ gcc -Wall -pedantic sw.c 
sw.c: In function 'main': 
sw.c:11: warning: ISO C forbids casts to union type 
sw.c:12: warning: ISO C forbids casts to union type