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:
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.
Sure about that ? ;)
As "i" is printed as 18446744073709551615 when put into cout, I
don't see how I couldn't be stored as a uint64...
It's actually -1 stored as an uint64.
This kind of optimizer problem is classical when mixing signed
and unsigned values into such bit shifting expressions.
This is why you should always cast the signed input values to the
unsigned result type right from the start before starting to
mix/shift them.