Thread overview | |||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 16, 2016 size_t index=-1; | ||||
---|---|---|---|---|
| ||||
should it be a compiler warning to assign a negative literal to an unsigned without a cast ? |
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laeeth Isharc | On Wednesday, 16 March 2016 at 18:40:56 UTC, Laeeth Isharc wrote: > should it be a compiler warning to assign a negative literal to an unsigned without a cast ? yes it should. https://issues.dlang.org/show_bug.cgi?id=3468 |
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laeeth Isharc | On Wednesday, March 16, 2016 18:40:56 Laeeth Isharc via Digitalmars-d-learn wrote:
> should it be a compiler warning to assign a negative literal to an unsigned without a cast ?
Maybe? It's a common enough thing to do that I'm willing to bet that Walter would object, but what you're really looking to do in most cases like that is to get something like uint.max, in which case it's better to just use the built-in constant. But I doubt that assigning negative literals to unsigned variables causes much in the way of bugs.
The bigger problem is comparing signed and unsigned types, and a number of folks have argued that that should be a warning or error.
- Jonathan M Davis
|
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laeeth Isharc | On 3/16/16 2:40 PM, Laeeth Isharc wrote:
> should it be a compiler warning to assign a negative literal to an
> unsigned without a cast ?
Why? They implicitly convert.
int x = -1;
uint y = x;
I don't see a difference between this and your code. And we can't change this behavior of the second line, too much arguably valid code would break.
-Steve
|
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 16 March 2016 at 20:11:41 UTC, Steven Schveighoffer wrote: > On 3/16/16 2:40 PM, Laeeth Isharc wrote: >> should it be a compiler warning to assign a negative literal to an >> unsigned without a cast ? > > Why? They implicitly convert. > > int x = -1; > uint y = x; > > I don't see a difference between this and your code. And we can't change this behavior of the second line, too much arguably valid code would break. > > -Steve We can change it, and we should. But it should be deprecated properly, and we should put in place enough candy to make it viable (See http://forum.dlang.org/post/vbeohujwdsoqfgwqgasa@forum.dlang.org ). |
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mathias Lang | On 3/16/16 4:55 PM, Mathias Lang wrote:
> On Wednesday, 16 March 2016 at 20:11:41 UTC, Steven Schveighoffer wrote:
>> On 3/16/16 2:40 PM, Laeeth Isharc wrote:
>>> should it be a compiler warning to assign a negative literal to an
>>> unsigned without a cast ?
>>
>> Why? They implicitly convert.
>>
>> int x = -1;
>> uint y = x;
>>
>> I don't see a difference between this and your code. And we can't
>> change this behavior of the second line, too much arguably valid code
>> would break.
>
> We can change it, and we should. But it should be deprecated properly,
> and we should put in place enough candy to make it viable (See
> http://forum.dlang.org/post/vbeohujwdsoqfgwqgasa@forum.dlang.org ).
No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this.
-Steve
|
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 16 March 2016 at 21:49:05 UTC, Steven Schveighoffer wrote:
> No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this.
>
> -Steve
I agree, but implicitly allowing for comparisons between the two allows for easy and *silent* mistakes. Also for comparisons of less-than-zero, for those functions we have that return -1 on failure.
import std.string : indexOf;
size_t pos = "banana".indexOf("c");
if (pos > 0) {
// oops
}
The above is naturally a programmer error but it's not something that will net you an immediate crash. It will just silently not behave as you meant, and you'll find yourself with a lot of fake bananas.
|
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anonymouse | On Wednesday, 16 March 2016 at 22:07:39 UTC, Anonymouse wrote:
>
> size_t pos = "banana".indexOf("c");
> if (pos > 0) {
Although I also think it makes sense to warn (in specific cases) about mixed-sign comparisons, the example you give here does nothing that we can warn about. It is a comparison of an unsigned "pos" with a literal that is unsigned too. ("0" literal must be considered signed and unsigned without any warnings)
|
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 16 March 2016 at 21:49:05 UTC, Steven Schveighoffer wrote:
> No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this.
>
> -Steve
I'm not talking about removing it completely. The implicit conversion should only happen when it's safe:
```
int s;
if (s >= 0) // VRP saves the day
{
uint u = s;
}
```
```
uint u;
if (u > short.max)
throw new Exception("Argument out of range");
// Or `assert`
short s = u;
```
|
March 16, 2016 Re: size_t index=-1; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mathias Lang | On Wednesday, March 16, 2016 22:37:40 Mathias Lang via Digitalmars-d-learn wrote:
> On Wednesday, 16 March 2016 at 21:49:05 UTC, Steven Schveighoffer
>
> wrote:
> > No, please don't. Assigning a signed value to an unsigned (and vice versa) is very useful, and there is no good reason to break this.
> >
> > -Steve
>
> I'm not talking about removing it completely. The implicit conversion should only happen when it's safe:
>
> ```
> int s;
> if (s >= 0) // VRP saves the day
> {
> uint u = s;
> }
> ```
>
> ```
> uint u;
>
> if (u > short.max)
> throw new Exception("Argument out of range");
> // Or `assert`
> short s = u;
> ```
Now, you're talking about comparing signed and unsigned values, which is a completely different ballgame. Just assigning one to the other really isn't a problem, and sometimes you _want_ the wraparound. If you assume that it's always the case that assigning a negative value to an unsigned type is something that programmers don't want to do, then you haven't programmed in C enough. And while it could still be done by requiring casts, consider that every time you do a cast, you're telling the compiler to just shut up and do what you want, which makes it easy to hide stuff that you don't want hidden - especially when code changes later.
D purposefully allows converting between signed and unsigned types of the same or greater size. And based on what he's said on related topics in the past, there's pretty much no way that you're going to convince Walter that it's a bad idea. And I really don't see a problem with the current behavior as far as assignment goes. It's comparisons which are potentially problematic, and that's where you'd have some chance of getting a warning or error added to the compiler. If you want to actually have the values check to ensure that a negative value isn't assigned to an unsigned integer, then use std.conv.to to do conversions or wrap your integers in types that have more restrictive rules. IIRC, at least one person around here has done that already so that they can catch integer overflow - which is basically what you're complaining about here.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation