Search code examples
cendiannessunsigned-char

shifting an unsigned char by more than 8 bits


I'm a bit troubled by this code:

typedef struct _slink{
    struct _slink* next;
    char type;
    void* data;
}

assuming what this describes is a link in a file, where data is 4bytes long representing either an address or an integer(depending on the type of the link)

Now I'm looking at reformatting numbers in the file from little-endian to big-endian, and so what I wanna do is change the order of the bytes before writing back to the file, i.e. for 0x01020304, I wanna convert it to 0x04030201 so when I write it back, its little endian representation is gonna look like the big endian representation of 0x01020304, I do that by multiplying the i'th byte by 2^8*(3-i), where i is between 0 and 3. Now this is one way it was implemented, and what troubles me here is that this is shifting bytes by more than 8 bits.. (L is of type _slink*)

int data = ((unsigned char*)&L->data)[0]<<24) + ((unsigned char*)&L->data)[1]<<16) + 
                    ((unsigned char*)&L->data)[2]<<8) + ((unsigned char*)&L->data)[3]<<0)

Can anyone please explain why this actually works? without having explicitly cast these bytes to integers to begin with(since they're only 1 bytes but are shifted by up to 24 bits) Thanks in advance.


Solution

  • Any integer type smaller than int is promoted to type int when used in an expression.

    So the shift is actually applied to an expression of type int instead of type char.