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