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);
        }                       
}

int promotion rule. char is signed. The 256 are signed. When the result goes above INT_MAX it overflows (i.e. we're in UB territory) and the result can be anything. The registers of the CPUs are 64 bit wide so it sign extends the calculation and as the optimization removes the truncating memory write and reload, the value of the complete register is then printed by the cout>>.

Conclusion: typical C(++) undefined behavior due to signed value overflow.
Fix: 256u
and always compile with -ftrapv . In your case it would have catched the overflow.

In D, signed overflow is not UB so everything works as planned.


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.


Reply via email to