Search code examples
cenumsunionspointer-aliasing

How to do aliasing with union or possible with enum?


I have gone through this very good article

https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule

but I didn't understood of aliasing with union, what I know about aliasing is with char/ unsigned char, which is a compiler exception according to this article. so , how I used to do aliasing with char/ unsigned char is like,

// lets say I have struct blah , having int member non_sense, cmmn_sense, intelligence...
struct blah *foo, *foo2;
unsigned char buffer [512];
foo = (struct blah *) (buffer+0);
//now accessing members
foo->non_sense = -1;
foo->non_snese = 0;
foo->intelligence =1;
// now we can use another struct after that ..
foo2 = (struct blah*) (buffer + sizeof(struct blah));

Please correct me if I am wrong some where :)

Q.So how can I do the same with union?

NOTE I didn't encountered with union much, so I don't know its proper use too.

I have also searched for aliasing with enum, but didn't understood much ,

Q.If possible with enum how will we do that?

Sorry for my English, not that good and please openly suggest correction for my misconception or terminology in my question to correct ...


Solution

  • Yes, almost any pointer (including your examples) is unsafe (except if it accessed by char).

    Below is safe (access by char pointer):

    struct blah x;
    char *y = (char *)&x;
    
    for(size_t i = 0; i < sizeof(x); i++)
       printf("[%zu] = %hhd\n", i, y[i];
    

    The correct way is to memcpy buffer into the struct or to have char array as one of the union members.

    struct a
    {
        int a;
        short b;
        char x[2];
        double z[3];
    };
    
    
    union b
    {
        unsigned char buffer[512];
        struct a sa[512/32];
    };
    
    double foo(char *x)
    {
        struct a c;
        memcpy(&c, x, sizeof(c));
        return c.z[0];
    }
    
    double bar(void)
    {
        union b c;
    
        read_from_uart(&c, 512);
    
        return c.sa[5].z[1];
    }
    

    Q.If possible with enum how will we do that? Enum is an integer. Same rules as for integers.