c++unsignedmodular-arithmetic

unsigned arithmetic - an indication that an overflow happened (ok! not happened but avoided by modular arithmetic)


I perform a subtraction with an unsigned type, say std::uint8_t. I can understand if the result will be obtained by modular arithmetic or not, by means of a comparison:

auto subtract (std::uint8_t x, std::uint8_t y) -> std::pair<std::uint8_t, bool>
{
return {x - y, x < y};
}

My question is the following: Can I avoid the comparison to know if modular arithmetic was in action or not? In other words, does the cpu provide an indication that it happened? Or shall I not worry: Would the compiler somehow optimize the subtraction and comparison operations somehow that the additional comparison won't introduce additional cost?

edt: adapt the example code so that the focus is on the question.


Solution

  • To expand on the comments, both your version and the version of @Andreas compile to the same asm (using clang):

    https://godbolt.org/z/qoq9ejEoa

    auto subtract26(std::uint8_t x, std::uint8_t y) -> std::pair<std::uint8_t, bool>
    {
        std::uint8_t result;
        bool overflow = ckd_sub( &result, x, y );
    
        return { result, overflow };
    }
    
    auto subtract(std::uint8_t x, std::uint8_t y) -> std::pair<std::uint8_t, bool>
    {
        return {x - y, x < y};
    }
    
    subtract26(unsigned char, unsigned char):
            xor     ecx, ecx
            sub     dil, sil
            setb    cl
            shl     ecx, 8
            movzx   eax, dil
            or      eax, ecx
            ret
    
    subtract(unsigned char, unsigned char):
            xor     ecx, ecx
            sub     dil, sil
            setb    cl
            shl     ecx, 8
            movzx   eax, dil
            or      eax, ecx
            ret
    

    So even if you do not have access to C++26, your compiler should be smart enough to optimize this :)