endolith
endolith

Reputation: 26813

Does self-assignment do anything during variable definition?

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

Answers (2)

Eric Postpischil
Eric Postpischil

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

0___________
0___________

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

Related Questions