Portability bug in integral conversion
Graham St Jack
Graham.StJack at internode.on.net
Sun Jan 16 15:24:35 PST 2011
On 16/01/11 08:52, Andrei Alexandrescu wrote:
> We've spent a lot of time trying to improve the behavior of integral
> types in D. For the most part, we succeeded, but the success was
> partial. There was some hope with the polysemy notion, but it
> ultimately was abandoned because it was deemed too difficult to
> implement for its benefits, which were considered solving a minor
> annoyance. I was sorry to see it go, and I'm glad that now its day of
> reckoning has come.
>
> Some of the 32-64 portability bugs have come in the following form:
>
> char * p;
> uint a, b;
> ...
> p += a - b;
>
> On 32 bits, the code works even if a < b: the difference will become a
> large unsigned number, which is then converted to a size_t (which is a
> no-op since size_t is uint) and added to p. The pointer itself is a
> 32-bit quantity. Due to two's complement properties, the addition has
> the same result regardless of the signedness of its operands.
>
> On 64-bits, the same code has different behavior. The difference a - b
> becomes a large unsigned number (say e.g. 4 billion), which is then
> converted to a 64-bit size_t. After conversion the sign is not
> extended - so we end up with the number 4 billion on 64-bit. That is
> added to a 64-bit pointer yielding an incorrect value. For the
> wraparound to work, the 32-bit uint should have been sign-extended to
> 64 bit.
>
> To fix this problem, one possibility is to mark statically every
> result of one of uint-uint, uint+int, uint-int as "non-extensible",
> i.e. as impossible to implicitly extend to a 64-bit value. That would
> force the user to insert a cast appropriately.
>
> Thoughts? Ideas?
>
>
> Andrei
It seems to me that the real problem here is that it isn't meaningful to
perform (a-b) on unsigned integers when (a<b). Attempting to clean up
the resultant mess is really papering over the problem. How about a
runtime error instead, much like dividing by 0?
--
Graham St Jack
More information about the Digitalmars-d
mailing list