Issue
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?
Solution
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:
- enum types, such as your
fiz_e
, are integer types. - All conversions, including those produced by typecast operators, are value-preserving when the value being converted is representable by the target data type.
- All of
int
,unsigned int
,uint32_t
(provided the implementation defines it), and yourfiz_e
can represent the value9
. int
andunsigned int
are not affected by the integer promotions, so there are no additional conversions performed on the arguments to yourprintf
call.- overall, the behavior you describe for the cross-compiled binary does not conform to the language specification.
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.
Answered By - John Bollinger Answer Checked By - Clifford M. (WPSolving Volunteer)