31-07-2008, 10:26 AM
On a 16 bit integer machine, the following happens. (Assume number represents the number of bits used for storage.)
Evaluation is left to right.
I have also changed the variables to u16a, u16b amd u32c.
u32c + u16a + u16b
u32c + u16a is evaluated in 32 bits unsigned.
x + u16b is added in 32bits unsigned.
Therefore, all operations have occured in one type.
But.
u16a + u16b + u32c
u16a + u16b is evaluated in 16 bits unsigned. Any overflow is handled by defined mod 65536.
x + u32c is evaluated in 32 bits unsigned.
There are therefore values of u16a, u16b and u32c for which
u32c + u16a + u16b is not equal to u16a + u16b + u32c
While the compiler's behaviour IS defined, the rule is intended to avoid such subtle differences.
Note that
(uint32_t) u16a + u16b + u32c is ok.
(uint32_t) u16a puts u16a into a 32 unsigned value.
x + u16b x is uint32_t, so is evaluated in 32 bit unsigned.
y + u32c is evaluated in 32 bit unsigned.
u16a + (uint32_t) u16b + u32c
(uint32_t) u16a + (uint32_t) u16b + u32c
would also work. The last line contains more than the minimum casting necessary to achieve consistant type.
I.e. consider
(uint32_t) u16a + u16b + u16c + ... + u16z + u32c
There is no need to clutter the code with a cast on every operator.
George
Evaluation is left to right.
I have also changed the variables to u16a, u16b amd u32c.
u32c + u16a + u16b
u32c + u16a is evaluated in 32 bits unsigned.
x + u16b is added in 32bits unsigned.
Therefore, all operations have occured in one type.
But.
u16a + u16b + u32c
u16a + u16b is evaluated in 16 bits unsigned. Any overflow is handled by defined mod 65536.
x + u32c is evaluated in 32 bits unsigned.
There are therefore values of u16a, u16b and u32c for which
u32c + u16a + u16b is not equal to u16a + u16b + u32c
While the compiler's behaviour IS defined, the rule is intended to avoid such subtle differences.
Note that
(uint32_t) u16a + u16b + u32c is ok.
(uint32_t) u16a puts u16a into a 32 unsigned value.
x + u16b x is uint32_t, so is evaluated in 32 bit unsigned.
y + u32c is evaluated in 32 bit unsigned.
u16a + (uint32_t) u16b + u32c
(uint32_t) u16a + (uint32_t) u16b + u32c
would also work. The last line contains more than the minimum casting necessary to achieve consistant type.
I.e. consider
(uint32_t) u16a + u16b + u16c + ... + u16z + u32c
There is no need to clutter the code with a cast on every operator.
George