digitalmars.D - Please tell me this is a bug?
- Almighty Bob (10/10) Feb 21 2015 D version 2.066.1
- Adam D. Ruppe (3/4) Feb 21 2015 Nope, a is clearly an int in the last case so no conversion is
- Almighty Bob (20/24) Feb 21 2015 a is an int in all three cases, b is a float in all three cases.
- Peter Alexander (3/9) Feb 21 2015 float does not *implicitly* convert to int. Required explicit
- Adam D. Ruppe (13/20) Feb 21 2015 Should 5.5 + 5 compile? I suppose it arguably shouldn't but
- Almighty Bob (19/26) Feb 22 2015 Float arithmetic is already lossy, almost every float operation
- Peter Alexander (5/14) Feb 21 2015 Not a bug. From spec:
- Adam D. Ruppe (5/6) Feb 21 2015 I actually agree it is a bit questionable, but I think the
- amber (6/13) Feb 21 2015 Isn't that a compiler implementation detail though?
- Peter Alexander (6/13) Feb 21 2015 I can see where you are coming from, but the fact of the matter
- deadalnix (5/20) Feb 21 2015 It is only equivalent for integral greater than int. It is not
- ketmar (14/32) Feb 21 2015 it's fuuuuuunny!
- ketmar (2/2) Feb 21 2015 On Sun, 22 Feb 2015 03:15:25 +0000, ketmar wrote:
- Daniel Kozak via Digitalmars-d (15/52) Feb 22 2015 nothing has change because you dont assign anything to v so I guess you
- ketmar (3/5) Feb 22 2015 i was trying to be smart, and failed. and i have a bad habit of noticing...
- deadalnix (9/25) Feb 21 2015 The rationale make sens for things like :
- Daniel Murphy (3/10) Feb 22 2015 We would still be able to accept that case if we required that the rhs
- Peter Alexander (12/42) Feb 22 2015 If VRP is unknown then it should be disallowed for precisely that
- Adam D. Ruppe (8/12) Feb 22 2015 Question though, how do you physically write the cast for:
- ponce (4/20) Feb 22 2015 Questionable or not, this is the C behaviour we might not depart
- Almighty Bob (10/23) Feb 22 2015 D has already departed from C,
- ketmar (3/24) Feb 22 2015 but compiler can at least warn about implicit converting float to int.=2...
- Steven Schveighoffer (16/31) Feb 23 2015 I think the docs are misleading.
D version 2.066.1 int a = 42; float b = 19; a = b; // Error: cannot implicitly convert expression (b) of type float to int a = a+b; // Error: cannot implicitly convert expression (b) of type float to int but... a += b; // Compiles with no ERROR! Please tell me that's a bug?
Feb 21 2015
On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:Please tell me that's a bug?Nope, a is clearly an int in the last case so no conversion is needed.
Feb 21 2015
On Sunday, 22 February 2015 at 01:32:16 UTC, Adam D. Ruppe wrote:On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:a is an int in all three cases, b is a float in all three cases. In one case the compiler automatically converts b to an int before adding it to a. In the other two cases it gives an error. So.. a=a+b; a+=b; Are not the same, OK, it seems odd that a "shorthand" version of an expression would have slightly different semantics than the longhand version but fundamentally what bothers me is any automatic conversion from float to int. It should never be automatic. Ok I looked up the docs, and they say... http://dlang.org/expression.html "Assign Expressions: The right operand is implicitly converted to the type of the left operand" which quite clearly is not the case since... a=b; // causes an error. but.. a+=b; // does not.Please tell me that's a bug?Nope, a is clearly an int in the last case so no conversion is needed.
Feb 21 2015
On Sunday, 22 February 2015 at 02:15:29 UTC, Almighty Bob wrote:"Assign Expressions: The right operand is implicitly converted to the type of the left operand" which quite clearly is not the case since... a=b; // causes an error. but.. a+=b; // does not.float does not *implicitly* convert to int. Required explicit coercion, which is what the opAssign expression does.
Feb 21 2015
On Sunday, 22 February 2015 at 02:15:29 UTC, Almighty Bob wrote:what bothers me is any automatic conversion from float to int. It should never be automatic.Should 5.5 + 5 compile? I suppose it arguably shouldn't but that'd probably be pretty annoying and no information is lost - it can convert 5 (the int) to 5.0 (the float) and add it without dropping a part of the number. But int = float would truncate the decimal and that's not cool. You could argue this same logic ought to apply to a+=b and you'd have a point, but I think it is different because += happens in a single step: calculate in-place, rather than calculate the right hand side then assign to the left hand side. There's no intermediate to lose precision from, it is all done in that single step."Assign Expressions: The right operand is implicitly converted to the type of the left operand" which quite clearly is not the case since... a=b; // causes an error. but..It tries to implicitly convert but can't.
Feb 21 2015
On Sunday, 22 February 2015 at 02:32:38 UTC, Adam D. Ruppe wrote:On Sunday, 22 February 2015 at 02:15:29 UTC, Almighty Bob wrote:Float arithmetic is already lossy, almost every float operation truncates and rounds, sticking an int in the mix does not change that. Int arithmetic is precise, putting a float in and automatically rounding it changes a precise equation to a lossy one. The point is if you have a float LHS then you are accepting lossy arithmetic as float is inherently lossy. If you have an int LHS you should be able to expect precise arithmetic. Most of what I do is DSP / data analysis. No only do I never want automatic float to int conversions, the majority of the time I actually want specific rounding when I do convert from float to int. IMO automatic float to int conversion is a terrible idea. It's worse than initialized floats because you can get results that look most OK, and it's a bugger to track down. And it's worse when the compiler has lulled you into a false sense of security by giving errors about not being able to convert floats to ints in most other cases.what bothers me is any automatic conversion from float to int. It should never be automatic.Should 5.5 + 5 compile? I suppose it arguably shouldn't but that'd probably be pretty annoying and no information is lost - it can convert 5 (the int) to 5.0 (the float) and add it without dropping a part of the number.
Feb 22 2015
On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:a += b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.
Feb 21 2015
On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:Seems questionable to me. Anyone know the rationale?I actually agree it is a bit questionable, but I think the difference is += is, conceptually at least, atomic - it is a single function, append() instead of two calls, set(calculate()).
Feb 21 2015
On Sunday, 22 February 2015 at 02:35:02 UTC, Adam D. Ruppe wrote:On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:Isn't that a compiler implementation detail though? I always considered a+=b as a shorthand for a=a+b so I find this surprising and a bit confusing. Maybe I need to revise my thinking on this :) /amberSeems questionable to me. Anyone know the rationale?I actually agree it is a bit questionable, but I think the difference is += is, conceptually at least, atomic - it is a single function, append() instead of two calls, set(calculate()).
Feb 21 2015
On Sunday, 22 February 2015 at 02:35:02 UTC, Adam D. Ruppe wrote:On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:I can see where you are coming from, but the fact of the matter is that it is evaluated no differently than a = a + b. Why, in the a += b case, does it somehow become acceptable for the compiler to irresponsibly insert in an implicit narrowing conversion?Seems questionable to me. Anyone know the rationale?I actually agree it is a bit questionable, but I think the difference is += is, conceptually at least, atomic - it is a single function, append() instead of two calls, set(calculate()).
Feb 21 2015
On Sunday, 22 February 2015 at 02:52:47 UTC, Peter Alexander wrote:On Sunday, 22 February 2015 at 02:35:02 UTC, Adam D. Ruppe wrote:It is only equivalent for integral greater than int. It is not for smaller integrals or floating point. See my other answer for rationale.On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:I can see where you are coming from, but the fact of the matter is that it is evaluated no differently than a = a + b. Why, in the a += b case, does it somehow become acceptable for the compiler to irresponsibly insert in an implicit narrowing conversion?Seems questionable to me. Anyone know the rationale?I actually agree it is a bit questionable, but I think the difference is += is, conceptually at least, atomic - it is a single function, append() instead of two calls, set(calculate()).
Feb 21 2015
On Sun, 22 Feb 2015 02:27:29 +0000, Peter Alexander wrote:On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:it's fuuuuuunny! struct A { int v =3D 40; this (int n) { v =3D n; } int opOpAssign(string op) (A b) { return v+b.v; } } void main () { auto a =3D A(); a +=3D (cast(A)5); // import std.stdio; writeln(a.v); // can you guess the output? } 'cmon, guess it without executing the code! but don't ask me why this=20 psychodelic code can be compiled at all.=a +=3D b; // Compiles with no ERROR! Please tell me that's a bug?=20 Not a bug. From spec: =20 http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: =20 a op=3D b =20 are semantically equivalent to: =20 a =3D cast(typeof(a))(a op b)=20 Seems questionable to me. Anyone know the rationale? If a =3D b; is disallowed, I don't see why a +=3D b; should be more acceptable.
Feb 21 2015
On Sun, 22 Feb 2015 03:15:25 +0000, ketmar wrote: ooops. it compiles 'cause it's ok, and i'm outsmarted myself. nevermind.=
Feb 21 2015
ketmar via Digitalmars-d píše v Ne 22. 02. 2015 v 03:15 +0000:On Sun, 22 Feb 2015 02:27:29 +0000, Peter Alexander wrote:nothing has change because you dont assign anything to v so I guess you mean this code?: import std.stdio; struct A { int v = 40; this (int n) { v = n; } void opOpAssign(string op) (A b) { v+=b.v; } } void main () { auto a = A(); a += (cast(A)5); writeln(a.v); // can you guess the output? } than it would be obviosly 45On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:it's fuuuuuunny! struct A { int v = 40; this (int n) { v = n; } int opOpAssign(string op) (A b) { return v+b.v; } } void main () { auto a = A(); a += (cast(A)5); // import std.stdio; writeln(a.v); // can you guess the output? } 'cmon, guess it without executing the code! but don't ask me why this psychodelic code can be compiled at all.a += b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.
Feb 22 2015
On Sun, 22 Feb 2015 21:08:34 +0100, Daniel Kozak via Digitalmars-d wrote:nothing has change because you dont assign anything to v so I guess you mean this code?:i was trying to be smart, and failed. and i have a bad habit of noticing=20 my dumbyness right after i pressed ctrl+enter.=
Feb 22 2015
On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:The rationale make sens for things like : byte a; a += 1; Here, because of type promotion, a + 1 is an int, and if VRP of a is unknown, you can't cast implicitly back to byte. It is true that this create questionable side effect for float, but in the end, that is consistent, and it would be very annoying to not be able to increment/decrement integral smaller than int.a += b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.
Feb 21 2015
"deadalnix" wrote in message news:wzpgqlnevhdmhsylumyq forum.dlang.org...The rationale make sens for things like : byte a; a += 1; Here, because of type promotion, a + 1 is an int, and if VRP of a is unknown, you can't cast implicitly back to byte. It is true that this create questionable side effect for float, but in the end, that is consistent, and it would be very annoying to not be able to increment/decrement integral smaller than int.We would still be able to accept that case if we required that the rhs implicitly converted to the rhs.
Feb 22 2015
On Sunday, 22 February 2015 at 07:11:24 UTC, deadalnix wrote:On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:If VRP is unknown then it should be disallowed for precisely that reason! It can't implicitly cast back to a byte, so it shouldn't. If you know that the int fits in a byte then do the cast yourself, that's what it's for.On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:The rationale make sens for things like : byte a; a += 1; Here, because of type promotion, a + 1 is an int, and if VRP of a is unknown, you can't cast implicitly back to byte.a += b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.It is true that this create questionable side effect for float, but in the end, that is consistent, and it would be very annoying to not be able to increment/decrement integral smaller than int.Even if you forget about float, it's still inconsistent. byte a; int b; a = a + b; a += b; These do the same thing, and have the same pitfalls if the int is too big. Both should be disallowed.
Feb 22 2015
On Sunday, 22 February 2015 at 14:18:24 UTC, Peter Alexander wrote:If VRP is unknown then it should be disallowed for precisely that reason! It can't implicitly cast back to a byte, so it shouldn't. If you know that the int fits in a byte then do the cast yourself, that's what it's for.Question though, how do you physically write the cast for: byte a; a += 1; With a + 1, you can cast that whole right hand side. But with +=1, there's nowhere to put the cast! If you cast(byte) 1, it changes nothing, since it could still overflow.
Feb 22 2015
On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:Questionable or not, this is the C behaviour we might not depart from.a += b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.
Feb 22 2015
On Sunday, 22 February 2015 at 09:59:36 UTC, ponce wrote:On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:D has already departed from C, int a; float b; a = b; a = a+b; a += b; All 3 are valid in C, but only the later is valid in D. But at least with MSVC you can get warnings when you do such things.Questionable or not, this is the C behaviour we might not depart from.are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.
Feb 22 2015
On Sun, 22 Feb 2015 09:59:35 +0000, ponce wrote:On Sunday, 22 February 2015 at 02:27:30 UTC, Peter Alexander wrote:but compiler can at least warn about implicit converting float to int.=20 one can always silence warning with `cast(int)f`. ER, anybody?=On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:=20 Questionable or not, this is the C behaviour we might not depart from.a +=3D b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: =20 a op=3D b =20 are semantically equivalent to: =20 a =3D cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a =3D b; is disallowed, I don't see why a +=3D b; should be more acceptable.
Feb 22 2015
On 2/21/15 9:27 PM, Peter Alexander wrote:On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote:I think the docs are misleading. For example, this doesn't work: int a; int *b = &a; a += b; Error: incompatible types for ((a) += (b)): 'int' and 'int*' But this does: a = cast(typeof(a))(a + b); I think it only works if it's a numeric narrowing conversion, but I don't know for sure. I would be happy if this behavior changed as the OP expected. But I'm glad there isn't exactly an unfettered implicit cast in every op= operation. Does anyone know the true rules for this, and can they please file an PR on the docs? -Stevea += b; // Compiles with no ERROR! Please tell me that's a bug?Not a bug. From spec: http://dlang.org/expression.html#AssignExpressionAssignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b)Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable.
Feb 23 2015