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 :)