Jump to page: 1 2
Thread overview
should int/short/byte implicitly cast to dchar/wchar/char?
May 16, 2011
KennyTM~
May 16, 2011
Jonathan M Davis
May 16, 2011
KennyTM~
May 16, 2011
Nick Sabalausky
May 17, 2011
Don
May 17, 2011
Jonathan M Davis
May 17, 2011
Walter Bright
May 17, 2011
Nick Sabalausky
May 17, 2011
KennyTM~
May 16, 2011
Currently, this works:

void foo(dchar i)
{
}

void main(string[] args)
{
    foo(args.length);
}

Does this make any sense?  When is it useful to be able to call a dchar-accepting function with a random integer?

I would say dchar should be settable from an (unsigned) integer literal (for those cases where you want to use a specific bit pattern), but from any integer or unsigned integer?

Same goes for short to wchar and byte to char, and the unsigned equivalents.

What do you think?

There is a bug report related to this:

http://d.puremagic.com/issues/show_bug.cgi?id=5995

-Steve
May 16, 2011
On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> Currently, this works:
>
> void foo(dchar i)
> {
> }
>
> void main(string[] args)
> {
>      foo(args.length);
> }

Damn, this originally started out as argc and argv, and I forgot how D accepts arguments, so I switched it to this.  Unsigned ints are convertable to dchar, but signed ones are not (except for a couple cases, which doesn't make sense).

For example, this fails:

dchar c = -1;
foo(-1);

But this passes:

int i = -1;
dchar c = i;

So clearly there are some inconsistencies that need to be fixed, but the situation is not as bad as I thought it was.

-Steve
May 16, 2011
On May 17, 11 02:25, Steven Schveighoffer wrote:
> On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>
>> Currently, this works:
>>
>> void foo(dchar i)
>> {
>> }
>>
>> void main(string[] args)
>> {
>> foo(args.length);
>> }
>
> Damn, this originally started out as argc and argv, and I forgot how D
> accepts arguments, so I switched it to this. Unsigned ints are
> convertable to dchar, but signed ones are not (except for a couple
> cases, which doesn't make sense).
>
> For example, this fails:
>
> dchar c = -1;
> foo(-1);
>

This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....

> But this passes:
>
> int i = -1;
> dchar c = i;

....but this cannot. 'dchar' should be treated as lower-rank than 'int' and use value-range propagation on it.

>
> So clearly there are some inconsistencies that need to be fixed, but the
> situation is not as bad as I thought it was.
>
> -Steve

May 16, 2011
On 2011-05-16 12:47, KennyTM~ wrote:
> On May 17, 11 02:25, Steven Schveighoffer wrote:
> > On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer
> > 
> > <schveiguy@yahoo.com> wrote:
> >> Currently, this works:
> >> 
> >> void foo(dchar i)
> >> {
> >> }
> >> 
> >> void main(string[] args)
> >> {
> >> foo(args.length);
> >> }
> > 
> > Damn, this originally started out as argc and argv, and I forgot how D accepts arguments, so I switched it to this. Unsigned ints are convertable to dchar, but signed ones are not (except for a couple cases, which doesn't make sense).
> > 
> > For example, this fails:
> > 
> > dchar c = -1;
> > foo(-1);
> 
> This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....
> 
> > But this passes:
> > 
> > int i = -1;
> > dchar c = i;
> 
> ....but this cannot. 'dchar' should be treated as lower-rank than 'int' and use value-range propagation on it.

I'd argue that assigning an int to a dchar should fail in all cases where there is no cast and where the compiler cannot use value-range propogation to verify that the value being assigned to the dchar is a valid value for a dchar. So, in the above case, if the compiler fails to do value-range propagation for some reason (which it shouldn't in a case this small), the assignment should be illegal, because there is no cast. And if the compiler manages to do value-range propagation (as it should), then it should still fail, because -1 is not a value value for a dchar.

- Jonathan M Davis
May 16, 2011
On Mon, 16 May 2011 15:47:55 -0400, KennyTM~ <kennytm@gmail.com> wrote:

> On May 17, 11 02:25, Steven Schveighoffer wrote:
>> On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer
>> <schveiguy@yahoo.com> wrote:
>>
>>> Currently, this works:
>>>
>>> void foo(dchar i)
>>> {
>>> }
>>>
>>> void main(string[] args)
>>> {
>>> foo(args.length);
>>> }
>>
>> Damn, this originally started out as argc and argv, and I forgot how D
>> accepts arguments, so I switched it to this. Unsigned ints are
>> convertable to dchar, but signed ones are not (except for a couple
>> cases, which doesn't make sense).
>>
>> For example, this fails:
>>
>> dchar c = -1;
>> foo(-1);
>>
>
> This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....

That is not what the error suggests:

Error: cannot implicitly convert expression (-1) of type int to dchar

Seems like it's the type that's failing.  At the very least, the error message should stress it's the value, not the type, that is the culprit.

If I change the literal to 0x10_ffff, indeed it passes, and 0x11_0000 fails.

I think this is probably the right behavior, it can be useful to use binary or hex numbers to construct characters.

>
>> But this passes:
>>
>> int i = -1;
>> dchar c = i;
>
> ....but this cannot. 'dchar' should be treated as lower-rank than 'int' and use value-range propagation on it.

I'm not sure what you mean, I think the dchar init statement should fail.  I think this is what you are saying, right?

Note in the bug report previously referenced, the compiler blindly accepts -1 as a dchar argument.

-Steve
May 16, 2011
On May 17, 11 03:58, Steven Schveighoffer wrote:
> On Mon, 16 May 2011 15:47:55 -0400, KennyTM~ <kennytm@gmail.com> wrote:
>
>> On May 17, 11 02:25, Steven Schveighoffer wrote:
>>> On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer
>>> <schveiguy@yahoo.com> wrote:
>>>
>>>> Currently, this works:
>>>>
>>>> void foo(dchar i)
>>>> {
>>>> }
>>>>
>>>> void main(string[] args)
>>>> {
>>>> foo(args.length);
>>>> }
>>>
>>> Damn, this originally started out as argc and argv, and I forgot how D
>>> accepts arguments, so I switched it to this. Unsigned ints are
>>> convertable to dchar, but signed ones are not (except for a couple
>>> cases, which doesn't make sense).
>>>
>>> For example, this fails:
>>>
>>> dchar c = -1;
>>> foo(-1);
>>>
>>
>> This fails because the compiler can check in compile-time that
>> 0xffff_ffff is > 0x10_ffff....
>
> That is not what the error suggests:
>
> Error: cannot implicitly convert expression (-1) of type int to dchar
>
> Seems like it's the type that's failing. At the very least, the error
> message should stress it's the value, not the type, that is the culprit.
>
> If I change the literal to 0x10_ffff, indeed it passes, and 0x11_0000
> fails.
>
> I think this is probably the right behavior, it can be useful to use
> binary or hex numbers to construct characters.
>
>>
>>> But this passes:
>>>
>>> int i = -1;
>>> dchar c = i;
>>
>> ....but this cannot. 'dchar' should be treated as lower-rank than
>> 'int' and use value-range propagation on it.
>
> I'm not sure what you mean, I think the dchar init statement should
> fail. I think this is what you are saying, right?
>

Right.

> Note in the bug report previously referenced, the compiler blindly
> accepts -1 as a dchar argument.
>
> -Steve

The compiler blindly accepts an 'int' as a 'dchar' argument, not -1. For instance,

void main(){
    string ret;
    ret ~= 0x10ffff;  // ok
    ret ~= 0x110000;  // Error: cannot append type int to type string
    int i = 0x110000;
    ret ~= i;         // ok, but should fail at compile time
}

the issue is also that an 'int' shouldn't be implicitly convertible to a 'dchar'.
May 16, 2011
On Mon, 16 May 2011 16:06:34 -0400, KennyTM~ <kennytm@gmail.com> wrote:

> The compiler blindly accepts an 'int' as a 'dchar' argument, not -1. For instance,
>
> void main(){
>      string ret;
>      ret ~= 0x10ffff;  // ok
>      ret ~= 0x110000;  // Error: cannot append type int to type string
>      int i = 0x110000;
>      ret ~= i;         // ok, but should fail at compile time
> }
>
> the issue is also that an 'int' shouldn't be implicitly convertible to a 'dchar'.

Yes, you are completely right, it seems the compiler isn't inconsistent WRT string appending and calling a normal function, it fails/passes the same way, depending on whether the argument passed is a variable or a literal.

So it seems the correct solution is for it to do range propagation, and refuse to compile implicit casts where it results in an invalid dchar (which includes the case where the int could be anything).

Sorry for the confusion, I thought I tested one thing, and actually tested another, yada yada...

-Steve
May 16, 2011
"Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.vvk48tn9eav7ka@localhost.localdomain...
>
(int/short/byte can sometimes implicitly cast to dchar/wchar/char)
>
> What do you think?
>

Ick! Kill it!


May 17, 2011
Nick Sabalausky wrote:
> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.vvk48tn9eav7ka@localhost.localdomain...
> (int/short/byte can sometimes implicitly cast to dchar/wchar/char)
>> What do you think?
>>
> 
> Ick! Kill it!
> 
> 

It's not easy. Simply disallowing it would make code like this illegal:

char c = '0' + n;


May 17, 2011
On 2011-05-16 21:04, Don wrote:
> Nick Sabalausky wrote:
> > "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message
> > news:op.vvk48tn9eav7ka@localhost.localdomain...
> > (int/short/byte can sometimes implicitly cast to dchar/wchar/char)
> > 
> >> What do you think?
> > 
> > Ick! Kill it!
> 
> It's not easy. Simply disallowing it would make code like this illegal:
> 
> char c = '0' + n;

Well, forcing the n to be cast to char or byte would do it, but that _is_ kind of ugly.

char c = '0' + cast(char)n;

Definitely a good point though.

- Jonathan M Davis
« First   ‹ Prev
1 2