digitalmars.D.announce - Re: dmd 1.046 and 2.031 releases
- bearophile <bearophileHUGS lycos.com> Jul 16 2009
- John C <johnch_atms hotmail.com> Jul 16 2009
- bearophile <bearophileHUGS lycos.com> Jul 16 2009
- BCS <ao pathlink.com> Jul 16 2009
- Don <nospam nospam.com> Jul 17 2009
- Don <nospam nospam.com> Jul 17 2009
- bearophile <bearophileHUGS lycos.com> Jul 17 2009
- Stewart Gordon <smjg_1998 yahoo.com> Jul 17 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Jul 17 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Jul 17 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Jul 16 2009
- Charles Hixson <charleshixsn earthlink.net> Jul 16 2009
- Jason House <jason.james.house gmail.com> Jul 16 2009
I'm playing with the new D2 a bit, this comes from some real D1 code: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); } At compile-time the compiler says: temp.d(3): Error: cannot implicitly convert expression (n <= 0 ? 0 : n >= 255 ? 255 : n) of type int to ubyte You have to add a silly cast: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : cast(ubyte)n)); } In theory if the compiler gets a smarter such cast can be unnecessary. Bye, bearophile
Jul 16 2009
bearophile Wrote:I'm playing with the new D2 a bit, this comes from some real D1 code: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); } At compile-time the compiler says: temp.d(3): Error: cannot implicitly convert expression (n <= 0 ? 0 : n >= 255 ? 255 : n) of type int to ubyte You have to add a silly cast: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : cast(ubyte)n)); } In theory if the compiler gets a smarter such cast can be unnecessary. Bye, bearophile
Did you not read the change log? "Implicit integral conversions that could result in loss of significant bits are no longer allowed."
Jul 16 2009
John C:Did you not read the change log? "Implicit integral conversions that could result in loss of significant bits are no longer allowed."
This was the code: ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); That last n is guaranteed to fit inside an ubyte (yes, I understand the compiler is not smart enough yet to understand it, but from the things explained by Andrei I have thought it was. So I am wrong and I have shown this to other people, that may be interested. I have also encouraged to make the compiler smarter to avoid a cast in such case, because this is a single expression, so range propagation is probably not too much hard to implement given the current design of the front-end. You have missed most of the purposes of my post). Bye, bearophile
Jul 16 2009
Reply to bearophile,John C:Did you not read the change log? "Implicit integral conversions that could result in loss of significant bits are no longer allowed."
ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); That last n is guaranteed to fit inside an ubyte (yes, I understand the compiler is not smart enough yet to understand it, but from the things explained by Andrei I have thought it was. So I am wrong and I have shown this to other people, that may be interested. I have also encouraged to make the compiler smarter to avoid a cast in such case, because this is a single expression, so range propagation is probably not too much hard to implement given the current design of the front-end. You have missed most of the purposes of my post). Bye, bearophile
I'm going with Steven on this one. Making the legality of code dependent on it's semantics is risky because it then ends up with bazaar portability issues or requiters that the scope of the semantics analysts engine be part of the language spec.
Jul 16 2009
BCS wrote:Reply to bearophile,John C:Did you not read the change log? "Implicit integral conversions that could result in loss of significant bits are no longer allowed."
ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); That last n is guaranteed to fit inside an ubyte (yes, I understand the compiler is not smart enough yet to understand it, but from the things explained by Andrei I have thought it was. So I am wrong and I have shown this to other people, that may be interested. I have also encouraged to make the compiler smarter to avoid a cast in such case, because this is a single expression, so range propagation is probably not too much hard to implement given the current design of the front-end. You have missed most of the purposes of my post). Bye, bearophile
I'm going with Steven on this one. Making the legality of code dependent on it's semantics is risky because it then ends up with bazaar portability issues or requiters that the scope of the semantics analysts engine be part of the language spec.
propagation of the ?: operator. I think the compiler should be required to do the semantics analysis for single expressions. Not more, not less.
Jul 17 2009
Steven Schveighoffer wrote:On Fri, 17 Jul 2009 08:08:23 -0400, Don <nospam nospam.com> wrote:In this case, I think bearophile's right: it's just a problem with range propagation of the ?: operator. I think the compiler should be required to do the semantics analysis for single expressions. Not more, not less.
Why? What is the benefit of keeping track of the range of integral variables inside an expression, to eliminate a cast? I don't think it's worth it. As far as I know, the ?: is the only expression where this can happen. You will get cries of inconsistency when the compiler doesn't allow: ubyte foo(uint x) { if(x < 256) return x; return 0; } -Steve
ubyte foo(uint n) { return true ? 255 : n; } And this fails: ubyte boo(uint n) { if (true) return 255; else return n; }
Jul 17 2009
Steven Schveighoffer:Does this compile: class C {} ubyte foo(C n) { return true ? 255 : n; } (don't have the latest compiler installed yet, so I couldn't check it myself)
It doesn't compile (DMD v2.031): temp.d(5): Error: incompatible types for ((255) ? (n)): 'int' and 'temp.C' Bye, bearophile
Jul 17 2009
BCS wrote:Reply to bearophile,John C:Did you not read the change log? "Implicit integral conversions that could result in loss of significant bits are no longer allowed."
ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); That last n is guaranteed to fit inside an ubyte
I'm going with Steven on this one. Making the legality of code dependent on it's semantics is risky because it then ends up with bazaar portability issues or requiters that the scope of the semantics analysts engine be part of the language spec.
For the record, Nice has a form of automatic downcasting that works something like this, though not AFAIK on numerical comparisons. To take an example from http://nice.sourceforge.net/safety.html#id2488356 : ---------- Component c = ...; ?List<Component> children; if (c instanceof ContainerComponent) children = c.getChildren(); else children = null; ---------- getChildren is a method of ContainerComponent, but not of general Component. The test performed in the condition of the if statement has the additional effect of casting c to a ContainerComponent within the if statement's body. Nice also has nullable and non-nullable types (note the ?) and, in the same way, it forces you to check that it isn't null before you try to dereference it. The principle could be applied to if statements and ?: expressions alike (as it would appear Nice does), and even && and || expressions. And it could be extended to arithmetic comparisons. A possible way is to spec that, if n is an int, and k is a compile-time constant >= 0, then given n >= k ? expr1 : expr2 any occurrence of n in expr1 is treated as cast(uint) n. And similarly for the other relational operators and other signed integer types. And then that, if u is of some unsigned integer type, and k is a compile-time constant within the range of u's type, then given u <= k ? expr1 : expr2 any occurrence of u in expr1 is treated as cast to the smallest unsigned integer type that u will fit into. And similarly for the other relational operators. Then your example would compile. However, - if we're going to do this, then for consistency we probably ought to define all literals to be of the smallest type they'll fit into, and prefer unsigned over signed, unless overridden with a suffix - we could go on defining rules like this for more complicated conditions, and it could get complicated - I'm not sure if this kind of automatic casting is desirable from a generic programming POV. Stewart.
Jul 17 2009
On Fri, 17 Jul 2009 08:08:23 -0400, Don <nospam nospam.com> wrote:In this case, I think bearophile's right: it's just a problem with range propagation of the ?: operator. I think the compiler should be required to do the semantics analysis for single expressions. Not more, not less.
Why? What is the benefit of keeping track of the range of integral variables inside an expression, to eliminate a cast? I don't think it's worth it. As far as I know, the ?: is the only expression where this can happen. You will get cries of inconsistency when the compiler doesn't allow: ubyte foo(uint x) { if(x < 256) return x; return 0; } -Steve
Jul 17 2009
On Fri, 17 Jul 2009 09:46:11 -0400, Don <nospam nospam.com> wrote:Steven Schveighoffer wrote:On Fri, 17 Jul 2009 08:08:23 -0400, Don <nospam nospam.com> wrote:In this case, I think bearophile's right: it's just a problem with range propagation of the ?: operator. I think the compiler should be required to do the semantics analysis for single expressions. Not more, not less.
variables inside an expression, to eliminate a cast? I don't think it's worth it. As far as I know, the ?: is the only expression where this can happen. You will get cries of inconsistency when the compiler doesn't allow: ubyte foo(uint x) { if(x < 256) return x; return 0; } -Steve
ubyte foo(uint n) { return true ? 255 : n; } And this fails: ubyte boo(uint n) { if (true) return 255; else return n; }
Does that require range propogation? That is, when the compiler sees: return true ? 255 does it even look at the type or range of the other branch? Does this compile: class C {} ubyte foo(C n) { return true ? 255 : n; } (don't have the latest compiler installed yet, so I couldn't check it myself) I think the situation is different because the compiler isn't forced to consider the other branch, it can be optimized out (I'm surprised it doesn't do that in the general if(true) case anyways, even with optimization turned off). -Steve
Jul 17 2009
On Thu, 16 Jul 2009 08:49:14 -0400, bearophile <bearophileHUGS lycos.com> wrote:I'm playing with the new D2 a bit, this comes from some real D1 code: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); } At compile-time the compiler says: temp.d(3): Error: cannot implicitly convert expression (n <= 0 ? 0 : n= 255 ? 255 : n) of type int to ubyte
You have to add a silly cast: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : cast(ubyte)n)); } In theory if the compiler gets a smarter such cast can be unnecessary.
I don't see how, doesn't this require semantic analysis to determine whether implicit casting is allowed? I think you are asking too much of the compiler. What if the expression was instead a function call, should the compiler look at the function source to determine whether it can fit in a ubyte? Where do you draw the line? I think the current behavior is fine. The D1 code probably works not because the compiler is 'smarter' but because it blindly truncates data. Perhaps if it were an optimization it could be implemented, but the result of an optimization cannot change the validity of the code... In other words, it couldn't be a compiler feature, it would have to be part of the spec, which would mean all compilers must implement it. BTW, I think cast is a perfect requirement here -- you are saying, yes I know the risks and I'm casting anyways. -Steve
Jul 16 2009
Steven Schveighoffer wrote:On Thu, 16 Jul 2009 08:49:14 -0400, bearophile <bearophileHUGS lycos.com> wrote:I'm playing with the new D2 a bit, this comes from some real D1 code: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); } At compile-time the compiler says: temp.d(3): Error: cannot implicitly convert expression (n <= 0 ? 0 : n= 255 ? 255 : n) of type int to ubyte
You have to add a silly cast: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : cast(ubyte)n)); } In theory if the compiler gets a smarter such cast can be unnecessary.
I don't see how, doesn't this require semantic analysis to determine whether implicit casting is allowed? I think you are asking too much of the compiler. What if the expression was instead a function call, should the compiler look at the function source to determine whether it can fit in a ubyte? Where do you draw the line? I think the current behavior is fine. The D1 code probably works not because the compiler is 'smarter' but because it blindly truncates data. Perhaps if it were an optimization it could be implemented, but the result of an optimization cannot change the validity of the code... In other words, it couldn't be a compiler feature, it would have to be part of the spec, which would mean all compilers must implement it. BTW, I think cast is a perfect requirement here -- you are saying, yes I know the risks and I'm casting anyways. -Steve
will fit into a ubyte without loss of information. Perhaps it's too much to ask. I'm not sure. I don't think he's sure. But if he doesn't ask, he won't find out. (And it sure would be nice to avoid casts in situations analogous to that.)
Jul 16 2009
bearophile Wrote:I'm playing with the new D2 a bit, this comes from some real D1 code: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : n)); } At compile-time the compiler says: temp.d(3): Error: cannot implicitly convert expression (n <= 0 ? 0 : n >= 255 ? 255 : n) of type int to ubyte You have to add a silly cast: void main(string[] args) { int n = args.length; ubyte m = (n <= 0 ? 0 : (n >= 255 ? 255 : cast(ubyte)n)); } In theory if the compiler gets a smarter such cast can be unnecessary. Bye, bearophile
add it to bugzilla.
Jul 16 2009
On Thu, Jul 16, 2009 at 6:43 PM, Jason House<jason.james.house gmail.com> w= rote:bearophile Wrote:I'm playing with the new D2 a bit, this comes from some real D1 code: void main(string[] args) { =A0 =A0 int n =3D args.length; =A0 =A0 ubyte m =3D (n <=3D 0 ? 0 : (n >=3D 255 ? 255 : n)); } At compile-time the compiler says: temp.d(3): Error: cannot implicitly convert expression (n <=3D 0 ? 0 : n=
You have to add a silly cast: void main(string[] args) { =A0 =A0 int n =3D args.length; =A0 =A0 ubyte m =3D (n <=3D 0 ? 0 : (n >=3D 255 ? 255 : cast(ubyte)n)); } In theory if the compiler gets a smarter such cast can be unnecessary. Bye, bearophile
add it to bugzilla.
Bearophile has never reported anything in Bugzilla. It's inexplicable. He constantly complains about D and does nothing to help it.
Jul 16 2009