Reputation: 26813
I have some code before me like this:
uint16_t a = a = (uint16_t) (bPtr);
Does this do anything special that I'm not aware of? Or is it equivalent to this:
uint16_t a = (uint16_t) (bPtr);
I'm guessing it's just a typo from combining
uint16_t a;
a = (uint16_t) (bPtr);
Upvotes: 0
Views: 140
Reputation: 222763
The intermixing of initialization and evaluation of expressions in initializers is not well defined by the C standard, particularly in regard to side effects in those initializers. However, uint16_t a = a = (uint16_t) (bPtr);
is best regarded as undefined behavior because it violates C 2018 6.5 2:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined…
In uint16_t a = a = (uint16_t) (bPtr);
, the assignment has the side effect of updating the scalar object a
. The initialization is not well defined in regard to whether it behaves like an assignment that occurs when the object is created. In the absence of such specification by the C standard, we should regard it as unsequenced relative to the assignment’s side effect, and therefore 6.5 2 renders the behavior of the program not defined by the C standard.
In contrast, uint16_t a = (uint16_t) (bPtr);
is fully defined (as long as bPtr
has been assigned a proper value).
The former code should never be used and should be corrected to the latter.
Upvotes: 4
Reputation: 67546
In this case, it does the same. No difference.
But if the variable is declared as volatile
it will write it twice. I was using on the hardware where (because of the silicon bug) one of the hardware registers had to be written twice
void writeREG(unsigned addr, uint32_t val)
{
*(volatile uint32_t *)addr = *(volatile uint32_t *)addr = val;
}
and the code:
writeREG:
str r1, [r0]
str r1, [r0]
bx lr
Upvotes: 1