digitalmars.D - should int/short/byte implicitly cast to dchar/wchar/char?
- Steven Schveighoffer (19/19) May 16 2011 Currently, this works:
- Steven Schveighoffer (15/23) May 16 2011 Damn, this originally started out as argc and argv, and I forgot how D
- KennyTM~ (5/30) May 16 2011 This fails because the compiler can check in compile-time that
- Jonathan M Davis (10/45) May 16 2011 I'd argue that assigning an int to a dchar should fail in all cases wher...
- Steven Schveighoffer (14/47) May 16 2011 That is not what the error suggests:
- KennyTM~ (13/63) May 16 2011 The compiler blindly accepts an 'int' as a 'dchar' argument, not -1. For...
- Steven Schveighoffer (11/22) May 16 2011 Yes, you are completely right, it seems the compiler isn't inconsistent ...
-
Nick Sabalausky
(4/5)
May 16 2011
"Steven Schveighoffer"
wrote in message - Don (3/12) May 16 2011 It's not easy. Simply disallowing it would make code like this illegal:
- Jonathan M Davis (6/18) May 16 2011 Well, forcing the n to be cast to char or byte would do it, but that _is...
- Walter Bright (7/15) May 16 2011 It's THE reason why such casts are not allowed. Pascal requires such cas...
- Nick Sabalausky (8/27) May 17 2011 I was going to suggest the rule:
- KennyTM~ (3/15) May 16 2011 It is already illegal. You cannot implicitly convert an 'int' to 'char'
- Steven Schveighoffer (20/30) May 17 2011 don't you mean dchar c = '0' + n?
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:This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....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;....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: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 DavisOn Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....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;....but this cannot. 'dchar' should be treated as lower-rank than 'int' and use value-range propagation on it.
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: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.On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....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);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. -SteveBut 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.
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:Right.On May 17, 11 02:25, Steven Schveighoffer wrote: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.On Mon, 16 May 2011 13:51:55 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:This fails because the compiler can check in compile-time that 0xffff_ffff is > 0x10_ffff....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);I'm not sure what you mean, I think the dchar init statement should fail. I think this is what you are saying, right?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.Note in the bug report previously referenced, the compiler blindly accepts -1 as a dchar argument. -SteveThe 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 16 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)It's not easy. Simply disallowing it would make code like this illegal: char c = '0' + n;What do you think?Ick! Kill it!
May 16 2011
On 2011-05-16 21:04, Don wrote:Nick Sabalausky wrote: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"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:op.vvk48tn9eav7ka localhost.localdomain... (int/short/byte can sometimes implicitly cast to dchar/wchar/char)It's not easy. Simply disallowing it would make code like this illegal: char c = '0' + n;What do you think?Ick! Kill it!
May 16 2011
On 5/16/2011 9:09 PM, Jonathan M Davis wrote:On 2011-05-16 21:04, Don wrote:It's THE reason why such casts are not allowed. Pascal requires such casts, and I always hated it for that. The casts are not only annoying, they can cause bugs when the types of the rest of the expression are changed in maintenance. There isn't any simple answer to mixed integer type arithmetic, although there are many "obvious" answers that have subtly pernicious behavior.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.
May 16 2011
"Walter Bright" <newshound2 digitalmars.com> wrote in message news:iqsu2b$1aqs$1 digitalmars.com...On 5/16/2011 9:09 PM, Jonathan M Davis wrote:I was going to suggest the rule: "char + numeric type == char" (and likewise for wchar/dchar), provided that the value range propogation works out, and if it doesn't then you do: char c = cast(char)('0' + n) Is that one of the "obvious" answers that has subtly pernicious behavior? If so, I'm curious what the problem with it is.On 2011-05-16 21:04, Don wrote:It's THE reason why such casts are not allowed. Pascal requires such casts, and I always hated it for that. The casts are not only annoying, they can cause bugs when the types of the rest of the expression are changed in maintenance. There isn't any simple answer to mixed integer type arithmetic, although there are many "obvious" answers that have subtly pernicious behavior.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.
May 17 2011
On May 17, 11 12:04, Don wrote:Nick Sabalausky wrote:It is already illegal. You cannot implicitly convert an 'int' to 'char' (Error: cannot implicitly convert expression (48 + n) of type int to char)."Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:op.vvk48tn9eav7ka localhost.localdomain... (int/short/byte can sometimes implicitly cast to dchar/wchar/char)It's not easy. Simply disallowing it would make code like this illegal: char c = '0' + n;What do you think?Ick! Kill it!
May 16 2011
On Tue, 17 May 2011 00:04:07 -0400, Don <nospam nospam.com> wrote:Nick Sabalausky wrote:don't you mean dchar c = '0' + n? And I wouldn't mind if dchar + int => dchar. I also wouldn't mind requiring a cast when range propagation proves the dchar could be invalid. In any case, I think: string s = "hello"; s ~= 123; looks like it should result in: assert(s == "hello123"); Especially anyone coming from any other language. They certainly would not expect it to be "hello{" To me, dchar is the more specialized type, it's like a typedef of uint -- you should be able to implicitly cast to uint/int, but not to dchar. It's kind of like a pointer, you can do this: int n; int* ptr; ptr += n; but you can't do this: ptr = n; -Steve"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:op.vvk48tn9eav7ka localhost.localdomain... (int/short/byte can sometimes implicitly cast to dchar/wchar/char)It's not easy. Simply disallowing it would make code like this illegal: char c = '0' + n;What do you think?Ick! Kill it!
May 17 2011