2010-01-27 10 views
14

Il seguente codice:Casting una costante a un sindacato

#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); 
} 

compila ed esegue correttamente con gcc. Se si tenta di trasmettere una costante per la quale non esiste un campo adatto nell'unione, viene generato un messaggio di errore.

Guardando allo standard (C99), tuttavia, non sono stato in grado di individuare la sezione in cui è descritto questo comportamento. Quindi, la mia domanda:

Ha la garanzia standard di C che posso lanciare una costante a un tipo di unione, a condizione che il tipo di unione è un campo con un tipo compatibile?

o, in altre parole:

È ((val_t)10) un rvalue valida di tipo val_t?

Sarebbe anche interessante sapere se questo comportamento è supportato da altri compilatori (o almeno MS Visual C++). Qualcuno lo sa?

MODIFICA: La trasmissione a un sindacato è un'estensione GCC, quindi non è una buona idea usarla.

Grazie a Maurits e Neil! Non ho pensato di usare -pedantic per controllare!

+1

A prescindere dal fatto che questo sembra un pessimo esercizio di programmazione, è una domanda interessante. Ho pensato che dopo 20 anni di programmazione in C l'ho visto tutto, Apparentemente no :) –

+1

@MauritsRijk In realtà è un ottimo modo per implementare contenitori generici in C. Si rende la chiave del contenitore un tipo di unione con campi come int , puntatore doppio e vuoto, e la funzione di confronto che si passa sa di quale tipo ha bisogno e accede al membro appropriato del sindacato. In realtà non vedo perché non è una parte standard della lingua, dal momento che il modo in cui i sindacati sono definiti in K & R, ogni membro è allineato con l'indirizzo più basso, l'unione è garantita per avere un corretto allineamento della memoria per tutti i suoi membri ed essere abbastanza largo da contenere il più largo. –

risposta

5

In GNU C language extensions il casting in unione è contrassegnato come estensione allo standard C. Quindi molto probabilmente non lo troverai nel C99 o in qualsiasi altro standard C. Il compilatore IBM C supporta anche questa estensione.

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 
Problemi correlati