Coda Coda - 2 months ago 15
C Question

C binary operator applyed on width of LVALUE or RVALUE

How does C handle binary operators? Does the standard require compilers to cast it to the LVALUE or needn't it?

The concrete problem I discovered looks as follows:

typedef union {
unsigned long _Data;
struct {
unsigned long _Reserved : 28;
unsigned long _Info : 1;
unsigned long _Reserved2 : 3;
};
} S_INFO;

S_INFO Variable;


With these defines, the instruction

Variable._Data &= ~3uL;


compiles different than the instruction

Variable._Data &= ~3u;


In the 16 bit architecture at hand, int is 2 bytes wide and long is 4 bytes wide.

The compiler seems to apply the & operator to the width of the literal (RVALUE), not to the width of the LVALUE Variable._Data.

Did I discover a a compiler bug or is this correct behaviour according to the C standard?

Answer

While waiting for you to post your findings as to precisely how the two fragments of code are compiled differently, (and since my comment appears to have prompted you to think of an answer, but I am not sure that this is the right answer,) let me just say that what is probably happening is this:

The instruction Variable._Data &= ~3uL; causes an unsigned long literal to be ANDed with a long value.

The instruction Variable._Data &= ~3u; takes an unsigned (not long) literal, zero-extends it to long, and then ANDs it with a long value.

So, these instructions compile differently most probably due to the way you declare the literal in the right operand. This probably has nothing to do with the left operand, nor with the operation that you are performing between the operands.

Anyhow, at this point, this is my guess; please post your findings as to precisely how the two fragments of code are compiled differently, and I may amend my answer.

Comments