简体   繁体   中英

Casting a char array to be of type struct *

In the code below could somebody perhaps explain what is happening on the line struct ether_header *eh = (struct ether_header *) sendbuf; ? I understand that it is creating a pointer eh of type ether_header and on the RHS you are casting sendbuf to be a pointer of tyoe struct ether_header . But how can you do this is sendbuf is a char array ? Also why would you do this?

Here is the link to the full code send ethernet frame

#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>

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;

But how can you do this is if sendbuf is a char array?

Code should not do this.

Casting a pointer to a type that was not originally a valid pointer for that type is undefined behavior (UB).

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

At a minimum, consider if struct ether_header had an alignment requirement to be an even address and sendbuf[] began on an odd address. The assignment may kill the program.

A 2nd concern is what unposted code might later do with sendbuf[] and eh which can violating strict aliasing rule @Andrew Henle .


A better approach is to use a union . Now the members are aligned and the union handles the strict aliasing rule.

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

Also why would you do this?

To allow access to the data from 2 data type perspectives. Perhaps to make a data dump of u .

The line char sendbuf[BUF_SIZ] allocates a block of chars (ie bytes on most systems) and the cast struct ether_header *eh = (struct ether_header *) sendbuf says that you explicitly want to treat this as a struct ether_header type. There are no significant instructions from this cast, aside from (possibly) setting a CPU register.

You'll end up with two pointers to the same block of memory. Modification of one will affect the other.

That being said, it is not completely correct/safe, because the sendbuf may not be appropriately aligned to actually contain a struct ether_header .

Edit: In regard to struct aliasing rules a char* is explicitly allowed to alias any other data type, but the reverse is not necessarily true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM