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:
I am not C++ expert so this seems wierd to me:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
char c = 0xFF;
std::string sData = {c,c,c,c};
unsigned int i = (((((sData[0]&0xFF)*256
+ (sData[1]&0xFF))*256)
+ (sData[2]&0xFF))*256
+ (sData[3]&0xFF));
if (i != 0xFFFFFFFF) { // it is true why?
// this print 18446744073709551615 wow
std::cout << "WTF: " << i << std::endl;
}
return 0;
}
compiled with:
g++ -O2 -Wall -o "test" "test.cxx"
when compiled with -O0 it works as expected
Vs. D:
import std.stdio;
void main(string[] args)
{
char c = 0xFF;
string sData = [c,c,c,c];
uint i = (((((sData[0]&0xFF)*256
+ (sData[1]&0xFF))*256)
+ (sData[2]&0xFF))*256
+ (sData[3]&0xFF));
if (i != 0xFFFFFFFF) { // is false - make sense
writefln("WTF: %d", i);
}
}
compiled with:
dmd -release -inline -boundscheck=off -w -of"test" "test.d"
So it is code gen bug on c++ side, or there is something wrong
with that code.
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.
It's signed overflow which is undefined behavior in C and C++.
He gets different results with and without optimization because
without optimization the result of the calculation is spilled to
the i unsigned int and then reloaded for the print call. This
save and reload truncated the value to its real value. In the
optimized version, the compiler removed the spill and the
overflowed value contained in the register is printed as is.