I'm trying to understand what does the following C function do?
void foo(char v[4]) {
int* p = (int*)v;
*p = (*p & 0x000000FF) << 24 |
(*p & 0x0000FF00) << 8 |
(*p & 0x00FF0000) >> 8 |
(*p & 0xFF000000) >> 24;
}
The possible solutions, by assuming that sizeof(int)
is 4, are four.
v
<-The function v
By doing int* p = (int*)v;
you can access now the bits in v
as if they were
the bits of an integer. But in this case, it is used to access the 32 bits
without having to cast from char
to int
to char
in all the swaps.
(*p & 0x000000FF)
returns you the first 8 bits (the least significant) [0 - 7]
(*p & 0x0000FF00)
returns you the next 8 bits [8 - 15]
(*p & 0x00FF0000)
returns you the next 8 bits [16 - 23]
(*p & 0xFF000000)
returns you the last 8 bits (most significant) [24 - 31]
This is basically doing: v[0]
, [v1]
, etc.
The << x
bits are left shifting, << 24
means that it moves all bits 24
spaces to the left. The |
makes an bitwise OR operation
(*p & 0x000000FF) << 24
Moves the bits [0-7] to the [24 - 31] position
(*p & 0x0000FF00) << 8
Moves the bits [8-15] to the [16 - 23] position
(*p & 0x00FF0000) >> 8
Moves the bits [16 - 23] to the [8 - 15] position
(*p & 0xFF000000) >> 24;
Moves the [23 - 31] to the [0 - 7] position.
It is reversing the order of the bytes pointed by v
.
edit
Like others have already pointed out, this reversing will only work in
environments where the size of a char[4]
is the same as the size of an int
.
Where those are different, the code becomes incorrect.
It interpretes a char[4] as integer and swaps it around:
(*p & 0x000000FF) << 24 == masks the lowes byte and puts it as highest byte
(*p & 0x0000FF00) << 8 == mask the 2nd lowest byte and puts it one higher
(*p & 0x00FF0000) >> 8 == masks the 2nd highest byte and shifts it one down
(*p & 0xFF000000) >> 24 == masks the highes byte and moves it to the lowest
all or-ed together it swaps your char array around.
It goes from ['a','b','c','d']
to ['d','c','b','a'].
And it smells. Badly.
Use a char
as temp and swap the elements of the arary using the temp is much more clear in "what does this" and much saver then this char-array to int pointer bitshift casting - what happens if you are on a system where char is 8 bits and int is 64 ?
User contributions licensed under CC BY-SA 3.0