On Tue, Dec 02, 2014 at 03:32:38PM -0800, Fred Cisin wrote:
. . .
>>> long long int A;
>>> int B;
>>> A = B << 32;
[...]
So, should the compiler optimize that to
MOV X,0
or
NOP
?
That basically depends on what "long long" and "int" means :)
The C99 (draft) standard says of << and >> that "[t]he behavior is
undefined if
the right operand is negative, or greater than or equal to the length in bits
of the promoted left operand", with the C++ standard using much the same words
but in a different order. There are all sorts of edge cases and caveats in the
standard, but I've not omitted anything relevant.
So on systems where sizeof(int) <= sizeof(int32_t) -- which is everything that
matters -- B << 32 is undefined and the compiler is permitted to do whatever it
damn well pleases, including invoking the infamous "nasal demons".
What *actually* happens depends on the compiler. Modern aggressive compilers
will go as far as to prove which code paths contain undefined behaviour and
thus treat so-affected variables and expressions as "poisoned". B would be
treated as unused here and its assignment would be optimised-away if not used
elsewhere. A would be treated as uninitialised, and thus potentially poison
anything that uses it, cascading the undefined behaviour further, allowing
whole swathes of code to be eliminated. With some of the compiler smarts
migrating into linkers, it may even take a crack at the halting problem and
optimise the whole program away because the standard allows it to!
(I am very much not a fan of C, but it helps to know one's enemies.)