For starters, the code that you gave won't even compile, because all integer math with sizes smaller than int
is done with int
. So the result of a + b
is int
, and int
will not implicitly convert to ubyte
, because that's a narrowing conversion. If you want to assign it to c
, then you'll need to cast it.
ubyte c = cast(ubyte)(a + b);
Now, that's obviously an unchecked conversion, and it will happily stuff 44
into c
(since that's the result of the cast given the values of 100
and 200
). If you want a checked conversion, then use std.conv.to
:
ubyte c = to!ubyte(a + b);
That will throw a ConvOverflowException
(which is a subclass of ConvException
), because the result won't fit in the requested type.
If you want to do the cast yourself and then check whether there was overflow, then you're in essentially the same boat as C/C++, and there are no carry flags or anything of the sort. Maybe that sort of thing exists if you check with assembly code. I don't know. But the language certainly doesn't provide anything like that. std.conv.to
figures it out by checking the result and seeing if it is too large or too small (depending on the sign and types of the argument).