char *ptr=buf;
This is not valid C. Since the pointer types are not compatible, this is a violation of the constraints for “simple assignment”. A compiler must give you a dignostic message like a warning. You can fix this by casting before assignment:char*ptr = (char*)buf;
buf[1]=0xCCBB;
etc stores the unsigned short in memory, and like any integer type it is stored according to endianess. In case you are using an x86 PC that’s little endian and 0xBB gets stored on the lowest address. That’s why they appear backwards when you later on print them byte by byte.printf("%X\t",*ptr);
A lot of strange things happen on this line.- First of all, we must learn that
char
has implementation-defined signedness, Is char signed or unsigned by default?. Therefore it is a type which should never be used for raw binary manipulation or any form of arithmetic. - On your specific compiler,
char
happened to be signed. printf
is a variadic function. Such functions are exotic (and bad practice) and come with a lot of special rules. One such special rule states that each parameter passed to a variadic function goes through a special kind of implicit promotion known as “the default argument promotions”. This rule says that all small integer types (such aschar
) are promoted to typeint
.- Whenever a signed
char
or any other small integer type is promoted to a larger signed type, it is sign extended, meaning that if it held a negative decimal value, the sign is preserved. - If your 8 bit signed
char
pointed at data0xAA
, then it gets treated as a negative number, since0xAA
is -86 decimal in 8-bit 2’s complement format. When this-86
value is converted to a 4 byte signedint
, the sign is preserved, it still has value-86
. But now the raw binary representation is0xFFFFFFAA
. This is why all your hex value bytes with MSB set got the 0xFFFFFF… appended to them, but those without the MSB set got printed as expected. - Finally,
%X
assumes that the passed parameter is anunsigned int
, soprintf
makes an internal conversion from your temporaryint
with value-86
into the unsigned equivalent0xFFFFFFAA
, which is what gets printed.
- First of all, we must learn that
We can fix the code like this:
#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t buf[50];
uint8_t* ptr = (uint8_t*)buf;
buf[0]=0xAAAA;
buf[1]=0xCCBB;
buf[2]=0x1234;
buf[3]=0xABCD;
for(int i=0; i<8; i++)
{
printf("%X\t",*ptr);
ptr++;
}
}
Here the same default argument promotion of uint8_t
to int
occurs, but this time the original data is treated like unsigned before promotion, so no sign extension happens.
CLICK HERE to find out more related problems solutions.