let's take the following code:
#include <stdio.h>
#include <inttypes.h>
typedef enum
{
BLAH = 9,
}fiz_e;
int main(void)
{
fiz_e foo = BLAH;
uint32_t bar = 9;
printf("foo d %d x 0x%08x\n",(int)foo,(unsigned int)foo);
if (bar == foo) printf("Hi\n");
if (bar == (uint32_t)foo) printf("Ho\n");
return 0;
}
Intuitively I would have said that this program displays:
foo d 9 x 0x00000009
Hi
Ho
BTW, this is also what I got when I compiled it on every online compiler I tried.
However, I'm (cross) compiling on a pulpino with riscv toolchain (riscv32-unknown-elf-gcc, gcc version 5.2.0), and I got the following result:
foo d 0 x 0x00000009
Ho
as if when not casting to uint32_t, it would take the msb and not truncate it...
Does endianness could explain this?
What does the standard say about this?
Intuitively I would have said that this program displays:
foo d 9 x 0x00000009 Hi Ho
Analytically, I would say that, too.
I got the following result:
foo d 0 x 0x00000009 Ho
as if when not casting to uint32_t, it would take the msb and not truncate it...
C doesn't work that way.
Does endianness could explain this?
No. The behaviors of arithmetic, comparison, and typecast operators are defined in terms of the value, not representation, of their operand(s), and it is the value of the result that is specified, not its representation.
What does the standard say about this?
Summarizing some of the relevant implications of the standard that have not already been covered:
fiz_e
, are integer types.int
, unsigned int
, uint32_t
(provided the implementation defines it), and your fiz_e
can represent the value 9
.int
and unsigned int
are not affected by the integer promotions, so there are no additional conversions performed on the arguments to your printf
call.Insufficient information is given to say what's wrong with your toolchain or execution environment, or with details of your usage of those, that produces the non-conforming behavior you describe.