Bitwise operations on enumeration types

When I tried to read data from memory into an enumeration through the following code, I got these strange results:

void read_memory (const unsigned, const unsigned, unsigned* const); /* ... */ enum {DATA_0, DATA_1, DATA_2} data; read_memory(base_addr, offset, &data); //data = 0x0900 data >>= 8; //data = 0x7e000000 

I worked on this by introducing a temporary variable of type unsigned. But I would like to make sure why the previous method does not work.

First of all, I know that the standard does not require a specific width for enumeration types if all elements can be represented. In fact, 6.7.2.2 says that:

Each numbered type must be compatible with char, a signed integer type, or an unsigned integer type.

But since the original data read from memory is placed in char, I think this should not be a problem. Moreover, if I understand correctly, “compatible” means that you can use it as if it were of this type. In particular, objects of an enumerated type can be operands of bitwise shift operators. I also know that signing can be a problem, because we don’t know if the listing is signed or not. But, as far as I can tell, 0x0900 is not signed.

So where is the problem?

+4
source share
3 answers

After testing the code outside the debugger, it turned out that it behaved correctly, and the information displayed by gdb was inaccurate.

In fact, analysis of the parsed machine code showed that it does not correspond to the numbers of the source lines of C. As a result, the function epilogue was considered (by gdb) as part of the command data >>= 8; . This problem remains strange for me, since I compiled and linked all the source and object files with -g -O0 .

Perhaps a bug in the compiler ...

Edit: this actually had nothing to do with gdb, these were the erroneous debugging symbols released by the compiler.

0
source

How much data is read by your (poorly named, in my opinion) read_memory() function? If this is not the same as the sizeof data value, you have a problem. Just because the listed values ​​are small enough for char does not mean that the compiler must select one char ; perhaps instructions for manipulating int dimensional numbers are faster and / or alignment problems may occur.

+2
source

Enumeration types are signed, so when shifting the sign bit (1) is copied by the numeric bits.

0
source

All Articles