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

Patrick Schluter Patrick.Schluter at bbox.fr
Tue Jul 24 15:08:35 UTC 2018


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.


More information about the Digitalmars-d mailing list