Is this strict aliasing example correct?

情到浓时终转凉″ 提交于 2019-12-05 01:16:45

There are no pointers and references anywhere in this code, so strict aliasing rules don't even enter the picture. And indeed the author invokes sequence points rather than strict aliasing to justify the assertion that it's undefined. However, it seems this reasoning is wrong and the code snippet has perfectly defined semantics. As Prasoon Saurav explains in more detail:

(§1.9/15) The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.

So regarding the = operator, the evaluation of a and (a >> 16) | (a << 16) are sequenced before the assignment. Neither of those is problematic: Although its parts are all unsequenced relative to each other, no write to a remains that would need to be sequenced.

(Technically this raises the question of how the side effect of the assignment is sequenced w.r.t. its value computation, but I couldn't find anything on this. Presumably it's somewhere in the standard but I don't have a copy handy. I strongly suspect it's sequenced after the value computation for the reasons in the next paragraph.)

You could also apply common sense: The write to a needs to evaluate (a >> 16) | (a << 16) first to write the right value and hence it can't happen in the middle of that evaluation. Another issue with the article is that even if

uint32_t
swaphalves(uint32_t a)
{
    a = (a >> 16) | (a << 16);
    return a;
}

had undefined behavior due to sequence points,

uint32_t
swaphalves(uint32_t a)
{
    return (a >> 16) | (a << 16);
}

wouldn't (there are no writes to be sequenced) and hence the far more complicated versions (unions, memcpy) that take up most of the rest of the article are pointless.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!