On Tuesday, 24 July 2018 at 20:59:22 UTC, Patrick Schluter wrote:
On Tuesday, 24 July 2018 at 19:24:05 UTC, Ecstatic Coder wrote:
On Tuesday, 24 July 2018 at 15:08:35 UTC, Patrick Schluter
wrote:
On Tuesday, 24 July 2018 at 14:41:17 UTC, Ecstatic Coder
wrote:
On Tuesday, 24 July 2018 at 14:08:26 UTC, Daniel Kozak wrote:
[...]
As the C++ char are signed by default, when you accumulate
several shifted 8 bit -1 into a char result and then store
it in a 64 bit unsigned buffer, you get -1 in 64 bits :
18446744073709551615.
That's not exactly what happens here. There's no 64 bit
buffer.
Sure about that ? ;)
Yes, there are no "buffers" only register and a place on the
stack for the variable i.
As said it's undefined behaviour so anything goes. I just
checked on godbolt what code is generated.
https://godbolt.org/g/wxqfmM
So with -O0 this happens:
From line 41 to line 77 the instruction to make the
calculation. At line 78
mov DWORD PTR [rbp-40], eax which is writing out 32 bits to
reserved space of i.
At line 85 mov eax, DWORD PTR [rbp-40] reloads that value in
eax, this annuls the high part of RAX => RAX contains
0x0000_0000_FFFF_FFFF
what I forgot to mention, for the compiler the type deduction for
the >> operator is done with the i variable, so it chooses the
right template with unsigned int. For the optimized code as the
calculation is done during compilation and there is no spill to
the variable the type deduction for the >> operator for cout is
done with that internal promoted temporary value and it deduces
it as long (funnily declaring i as volatile doesn't change that
even if the value is spilled to the stack).
On the -O2 version it's even simpler. The calculation is done
at compile time and the endresult -1 is put directly to the
output. The test is even removed. Everything happens in the
compiler.