Lanciare un array di caratteri in modo che sia di tipo struct *

Nel codice seguente qualcuno potrebbe forse spiegare cosa sta succedendo sulla linea struct ether_header *eh = (struct ether_header *) sendbuf; ? Capisco che stia creando un puntatore eh di tipo ether_header e ether_header che stai sendbuf per essere un puntatore di tyoe struct ether_header . Ma come puoi fare questo è sendbuf è un char array ? Anche perché lo faresti?

Ecco il link per il codice completo invia frame ethernet

 #include  #include  #include  #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]) { int sockfd; struct ifreq if_idx; struct ifreq if_mac; int tx_len = 0; char sendbuf[BUF_SIZ]; struct ether_header *eh = (struct ether_header *) sendbuf; 

Ma come puoi farlo se sendbuf è un array di char ?

Il codice non dovrebbe farlo.

Lanciare un puntatore a un tipo che non era originariamente un puntatore valido per quel tipo è un comportamento non definito (UB).

 char sendbuf[BUF_SIZ]; struct ether_header *eh = (struct ether_header *) sendbuf; // UB 

Come minimo, considerare se struct ether_header avesse un requisito di allineamento come indirizzo pari e sendbuf[] iniziato su un indirizzo dispari. L’incarico potrebbe uccidere il programma.

Una seconda preoccupazione è quale codice non pubblicato potrebbe in seguito fare con sendbuf[] ed eh che possono violare la regola di aliasing rigorosa @Andrew Henle .


Un approccio migliore è usare un union . Ora i membri sono allineati e l’ union gestisce la rigida regola di aliasing.

 union { char sendbuf[BUF_SIZ]; struct ether_header eh; } u; 

Anche perché lo faresti?

Per consentire l’accesso ai dati da 2 prospettive di tipo di dati. Forse per fare un dump di dati di te.

La riga char sendbuf[BUF_SIZ] alloca un blocco di caratteri (cioè i byte sulla maggior parte dei sistemi) e la struct ether_header *eh = (struct ether_header *) sendbuf cast struct ether_header *eh = (struct ether_header *) sendbuf dice che si desidera esplicitamente trattarlo come un tipo struct ether_header . Non ci sono istruzioni significative da questo cast, a parte (forse) l’impostazione di un registro della CPU.

Finirai con due puntatori allo stesso blocco di memoria. La modifica di una influenzerà l’altra.

Detto questo, non è completamente corretto / sicuro, perché sendbuf potrebbe non essere allineato in modo appropriato per contenere effettivamente una struct ether_header .

Modifica: per quanto riguarda le regole di aliasing della struttura, un char* è esplicitamente autorizzato ad aliasare qualsiasi altro tipo di dati, ma il contrario non è necessariamente vero.