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.

Reply via email to