I came across the following #define in third party code:
#define Endian_StreamGetLittleInt(ppBytes) \
(int) ((++*(int **)(ppBytes)), \
( ((*(char **)(ppBytes))[3-sizeof(int)] << 24) \
| ((*(char **)(ppBytes))[2-sizeof(int)] << 16) \
| ((*(char **)(ppBytes))[1-sizeof(int)] << 8) \
| ((*(char **)(ppBytes))[0-sizeof(int)])) )
And it’s used as follows:
int uiSize = Endian_StreamGetLittleInt(&buf);
where buf is a char * that points to a number of bytes of data that were previously read from a file.
I understand the bitshift section as rearranging the bytes as they appear in the byte array to match the endianness of the platform (or perhaps someone can correct me). However, I’m puzzled over the use of:
(++*(int **)(ppBytes)) ,
Why is there a comma there?
What you have is an expression consisting of two sub-expressions, joined by the comma operator. The first expression increments the pointer by one integer step. No matter the actual type of the pointer, it is cast to an
int**first, then dereferenced to anint*and thatint*is then incremented. As a result, the address pointed to will change bysizeof(int)bytes.As the comma operator will always execute its first argument first, but return the value of its second argument, you see the increment first and then the value computation. But if you look closer, you’ll see that the second argument does use negative indices, so it will reference the number that the pointer was pointing at before it got incremented.