Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
February 20, 2014 Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
The following statement prints false: writeln(-1 < uint.max); This came up in another topic recently. I think this is silly and an unnecessary source of bugs (it's bitten me before and presumably many others as well). I'm making a proposal to add an extra check so that comparisons of signed with unsigned types is always correct. Simply, if the signed type is negative, it is by default less than the unsigned value. The compiler has all the information it needs at compile time to add this check where necessary. I demonstrate the problem and solution here: http://dpaste.dzfl.pl/acd819d1a9ea Others have suggested disallowing comparing a signed type with an unsigned type. I think this is a better solution. Yes, it will add a small bit of overhead, but I believe it's more important for code to be correct than to be fast. Any takers? |
February 20, 2014 Re: Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | On Thursday, 20 February 2014 at 20:52:23 UTC, Xinok wrote:
> The following statement prints false:
>
> writeln(-1 < uint.max);
>
> This came up in another topic recently. I think this is silly and
> an unnecessary source of bugs (it's bitten me before and
> presumably many others as well). I'm making a proposal to add an
> extra check so that comparisons of signed with unsigned types is
> always correct. Simply, if the signed type is negative, it is by
> default less than the unsigned value. The compiler has all the
> information it needs at compile time to add this check where
> necessary. I demonstrate the problem and solution here:
>
> http://dpaste.dzfl.pl/acd819d1a9ea
>
> Others have suggested disallowing comparing a signed type with an
> unsigned type. I think this is a better solution. Yes, it will
> add a small bit of overhead, but I believe it's more important
> for code to be correct than to be fast.
>
> Any takers?
This will silently change the semantics of any C code compiled with DMD (even if those semantics were extremely bug prone in the first place). Is this a good or bad thing? I can't think of any C code that would rely on such behaviour, but I think it'd just be safer all-around to make it an error.
|
February 21, 2014 Re: Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | On Thursday, 20 February 2014 at 20:52:23 UTC, Xinok wrote: > The following statement prints false: > > writeln(-1 < uint.max); I don't see this as a bug, this is exactly what I expect from a language with intact C integer semantics. > This came up in another topic recently. I think this is silly and > an unnecessary source of bugs (it's bitten me before and > presumably many others as well). I'm making a proposal to add an > extra check so that comparisons of signed with unsigned types is > always correct. Simply, if the signed type is negative, it is by > default less than the unsigned value. That subtly breaks C compatiblity. > Others have suggested disallowing comparing a signed type with an > unsigned type. I think this is a better solution. Currently in C the unsigned vs signed operations all follow the same rules. If you do this, would you also disallow unsigned vs signed addition, subtraction, divide? I feel this would make porting C code much longer, and it's already quite a bit of work. |
February 21, 2014 Re: Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Thursday, 20 February 2014 at 22:52:55 UTC, Meta wrote:
> I can't think of any C code that would rely on such behaviour, but I think it'd just be safer all-around to make it an error.
Eg this optimization:
if ((unsigned int)(a - min) < (max - min)) // only one comparison instead of two
{
}
And there is many C codes relying on unsigned promotion, since signed overflow in C99 is undefined behaviour. The easiest way to force an operation is then to use one cast.
|
February 21, 2014 Re: Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | On Thursday, 20 February 2014 at 20:52:23 UTC, Xinok wrote: > Others have suggested disallowing comparing a signed type with an > unsigned type. I think this is a better solution. Yes, it will > add a small bit of overhead, but I believe it's more important > for code to be correct than to be fast. I totally agree. However, since we need correct code, we need way more features than this. I was surprised to find out that we don't have any "SafeInt" type in D... I was sure someone had made it but I wasn't able to find it anywhere. My ideal int type: -Has an equivalent of NaN, meaning it doesn't have "0 initialization" which is somewhat bug-prone. -Is able to signal errors like overflow/division by zero, would be nice if throwing could be avoided. -Signed, but can be flagged as ">0 only", and signals an error if it gets assigned a negative value. -Some extra features that are surely awesome but I'm forgetting right now. > Any takers? Man, I wish I had time :S |
February 21, 2014 Re: Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | On 20/02/2014 20:52, Xinok wrote: > Others have suggested disallowing comparing a signed type with an > unsigned type. Yes, that solution is pre-approved: https://d.puremagic.com/issues/show_bug.cgi?id=259 I think that's a very important bug to solve. |
February 21, 2014 Re: Correct comparison of signed type with unsigned type (and vice versa) | ||||
---|---|---|---|---|
| ||||
Posted in reply to ponce | On Friday, 21 February 2014 at 10:45:50 UTC, ponce wrote: > I don't see this as a bug, this is exactly what I expect from a language with intact C integer semantics. I didn't call it a bug. I said that it's prone to causing bugs. > That subtly breaks C compatibility. Personally, I wish we would drop some of the C semantics and allow the language evolve. In it's place, add a function attribute which would enable C semantics for the sake of migrating code. > Currently in C the unsigned vs signed operations all follow the same rules. If you do this, would you also disallow unsigned vs signed addition, subtraction, divide? Unfortunately, those operations don't have such simple solutions. D is a statically typed language and the compiler simply can't predict what the resultant type should be. However, comparisons do have a simple fix with minimal overhead. |
Copyright © 1999-2021 by the D Language Foundation