Comparing D vs C++ (wierd behaviour of C++)

Ecstatic Coder ecstatic.coder at gmail.com
Tue Jul 24 19:24:05 UTC 2018


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.



More information about the Digitalmars-d mailing list