March 29, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MattCoder | On Friday, 28 March 2014 at 19:57:13 UTC, MattCoder wrote:
> On Friday, 28 March 2014 at 19:35:22 UTC, Frustrated wrote:
>> which means, i = is the previous value of j(before increment).
>> This should hold true when j is an alias for i.
>
> In this case: i = i++; Means:
>
> "i" is incremented by one, but the value assigned in "i" is the
> previous one. That's it.
>
> For me there's nothing wrong here.
>
> Matheus.
One thing you are getting wrong/leaving out is that i++, even in an assignment, increments i.
i = j++;
even if i is assigned the previous value of j, j STILL gets incremented by one.
Change i to j and it will work out.
Only if a temp value can the D behavior work as it does. This is wrong though because not all compilers have to use temp values.
Again, it is also inconsistent with the fact that something should get incremented.
"If ++ follows the variable, e.g. counter++, the value returned is the value in counter before it has been incremented. "
i = i++;
=> i = i; // value before i is incremented
i++; // now it is incremented.
which increments i due to last statement.
You can't increment i until you return the value.
mov ax, [i] // put i in a register
mov ax, ax // i = i // easily optimized out
inc ax // i++
mov [i], ax
vs
mov ax, [i]
mov bx, ax
mov ax, bx
inc bx
mov [i], ax
I think most people would agree that the 2nd case is worse(one extra register is used for no real reason except to avoid the increment).
|
March 29, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On 03/29/2014 05:31 PM, Frustrated wrote: > .. i++, even in an assignment, increments i. > ... TDPL specifies the behaviour of i++ as follows: {auto tmp=i; ++i; return tmp;}(); > i = j++; > ... i = {auto tmp=i; ++j; return tmp;}(); > even if i is assigned the previous value of j, j STILL gets incremented > by one. > > Change i to j and it will work out. > ... i = {auto tmp=i; ++i; return tmp;}(); |
March 29, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On Saturday, 29 March 2014 at 16:31:48 UTC, Frustrated wrote: > On Friday, 28 March 2014 at 19:57:13 UTC, MattCoder wrote: >> On Friday, 28 March 2014 at 19:35:22 UTC, Frustrated wrote: >>> which means, i = is the previous value of j(before increment). >>> This should hold true when j is an alias for i. >> >> In this case: i = i++; Means: >> >> "i" is incremented by one, but the value assigned in "i" is the >> previous one. That's it. >> >> For me there's nothing wrong here. >> >> Matheus. > > > One thing you are getting wrong/leaving out is that i++, even in an assignment, increments i. I see your pain pal... so I took a look around: http://dlang.org/expression.html And according the page above: "Expressions C and C++ programmers will find the D expressions very familiar, with a few interesting additions. Expressions are used to compute values with a resulting type. These values can then be assigned, tested, or ignored. Expressions can also have side effects. Order Of Evaluation The following binary expressions are evaluated in strictly left-to-right order: [i] OrExpression, XorExpression, AndExpression, CmpExpression, ShiftExpression, AddExpression, CatExpression, MulExpression, PowExpression, CommaExpression, OrOrExpression, AndAndExpression [/i] The following binary expressions are evaluated in an implementation-defined order: AssignExpression, function arguments It is an error to depend on order of evaluation when it is not specified. For example, the following are illegal: i = i++;" Matheus. |
March 30, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MattCoder | > For example, the following are illegal:
> i = i++;"
so we have bug in compiler: it should not accept illegal expressions.
|
March 30, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MattCoder | On Saturday, 29 March 2014 at 17:29:51 UTC, MattCoder wrote:
> On Saturday, 29 March 2014 at 16:31:48 UTC, Frustrated wrote:
>> On Friday, 28 March 2014 at 19:57:13 UTC, MattCoder wrote:
>>> On Friday, 28 March 2014 at 19:35:22 UTC, Frustrated wrote:
>>>> which means, i = is the previous value of j(before increment).
>>>> This should hold true when j is an alias for i.
>>>
>>> In this case: i = i++; Means:
>>>
>>> "i" is incremented by one, but the value assigned in "i" is the
>>> previous one. That's it.
>>>
>>> For me there's nothing wrong here.
>>>
>>> Matheus.
>>
>>
>> One thing you are getting wrong/leaving out is that i++, even in an assignment, increments i.
>
> I see your pain pal... so I took a look around:
> http://dlang.org/expression.html
>
> And according the page above:
>
> "Expressions
>
> C and C++ programmers will find the D expressions very familiar,
> with a few interesting additions.
>
> Expressions are used to compute values with a resulting type.
> These values can then be assigned, tested, or ignored.
> Expressions can also have side effects.
>
> Order Of Evaluation
>
> The following binary expressions are evaluated in strictly
> left-to-right order:
> [i]
> OrExpression, XorExpression, AndExpression, CmpExpression,
> ShiftExpression, AddExpression, CatExpression, MulExpression,
> PowExpression, CommaExpression, OrOrExpression, AndAndExpression
> [/i]
>
> The following binary expressions are evaluated in an
> implementation-defined order:
>
> AssignExpression, function arguments
>
> It is an error to depend on order of evaluation when it is not
> specified. For example, the following are illegal:
>
> i = i++;"
>
> Matheus.
My only point is that monarch was wrong ;) Trying to justify how dmd does it is like trying to prove your conclusion by stating it as a hypothesis. Regardless if the correct behavior is to increment i(which I think it should) or for it to be illegal, the wrong behavior is to leave i unchanged. Luckily I'd never write such a statement but I wonder if there are more complex cases that produce wrong behavior?
|
March 31, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On Sat, 29 Mar 2014 16:21:54 +0000, Frustrated wrote:
>
> Oh yeah, this makes hell of a lot of sense. I'm the one who's wrong, yet monarch claims it his is correct and yet clang gives a warning. Great logic there! I'll be sure to mark every post you have as special so I can study your logic to become so smart.
Trying to insult me isn't going to make you right, nor will an appeal to unicorns. With a well-defined order-of-operations, this might be correct behavior; in this case I suspect D is like C and that this is undefined behavior, thus I would support making this statement illegal or at least warning. At any rate you are demonstrably incorrect about D differing from the behavior of all other C-family languages--so unless you want to go flame on the GCC and Clang mailing-lists, I suggest you dial it back.
Cheers,
Justin
|
March 31, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frustrated | On Friday, 28 March 2014 at 18:04:41 UTC, Frustrated wrote:
> On Friday, 28 March 2014 at 16:54:49 UTC, Benjamin Thaut wrote:
>> I had a bug which came down to the following line today:
>>
>> m_takeIndex = m_takeIndex++;
>>
>> Actually this line does nothing. m_takeIndex remains at exactly the same value as before (tested with dmd 2.065).
>>
>> Can someone please explain why? And would be suitable to warn about this, if it is correct behaviour?
>>
>> Kind Regards
>> Benjamin Thaut
>
> This should be invalid.
>
> m_takeIndex++;
>
> actually increments the variable.
>
> m_takeIndex = m_takeIndex++; should do exactly the same.
Nope. Nope nope nope. That's not what postfix increment is. That's why prefix increment exists.
Yeah, it might be an odd design (dates back to poor optimising compilers and fast INC/DEC instructions apparently), but that's how it is in C and how it is in D, by inheritance.
|
March 31, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Justin Whear | On Monday, 31 March 2014 at 15:51:03 UTC, Justin Whear wrote: > Trying to insult me isn't going to make you right, nor will an appeal to > unicorns. With a well-defined order-of-operations, this might be correct > behavior; Actually, regardless of order of operation, specs says you still get "i" un-incremented, since opEquals's lhs has no side effects anyways. ...The only way to have some other result, is if there was some sort of undefined behavior in the statement, at which point there is no more concept of "correct behavior" > in this case I suspect D is like C and that this is undefined > behavior Yup. It's undefined behavior. I replied too fast and missed it. > thus I would support making this statement illegal or at least > warning. The issue is that the legality of this can't be checked at the semantic phase. It depends on *who* the left and right hand sides are. It's obvious in "i = i++;", but if you start mixing function calls, references and whatnot, the line becomes more blurry: //---- int i; auto p = &i; *p = i++; //Legal? Illegal? //---- So this means making it illegal is out of the question. As for making it a warning, well, Walter is (AFAIK) pretty much against having any warnings at all, short of straight up deterministic semantic warnings "dangling else"/"deprecation". |
March 31, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Monday, 31 March 2014 at 15:56:29 UTC, John Colvin wrote:
>> m_takeIndex = m_takeIndex++; should do exactly the same.
>
> Nope. Nope nope nope. That's not what postfix increment is. That's why prefix increment exists.
>
> Yeah, it might be an odd design (dates back to poor optimising compilers and fast INC/DEC instructions apparently), but that's how it is in C and how it is in D, by inheritance.
I just don't see, why one would expect the assignment could come first?!?
The post-increment has a much, much higher priority, so I would think it is obvious that first the value is incremented and afterwards the old value is assigned to it.
And of course, the old, non-incremented value is assigned. This is the essence od POST incrementing - the return value of this operator is defined to be the old value, that's the whole point why this operator exists. (btw. I would _never_ever_ write a line like "i++;" That's garbage. It should always be "++i;"
Yes, the optimizer will get rid of the temporary variable, but it is absolutely unintuitive (if I read something like that my first thought is: what is the
old value used for? Why using a temporary variable?)
But I fully agree that such a form of complicated NOP ("i = i++;") should be forbidden or at least warned about.
|
March 31, 2014 Re: Warn about do nothing expressions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Mon, 31 Mar 2014 16:07:25 +0000, monarch_dodra wrote:
>
> The issue is that the legality of this can't be checked at the semantic phase.
>
> It depends on *who* the left and right hand sides are. It's obvious in "i = i++;", but if you start mixing function calls, references and whatnot, the line becomes more blurry:
>
> //----
> int i;
> auto p = &i;
> *p = i++; //Legal? Illegal?
> //----
>
> So this means making it illegal is out of the question.
>
> As for making it a warning, well, Walter is (AFAIK) pretty much against having any warnings at all, short of straight up deterministic semantic warnings "dangling else"/"deprecation".
Yeah, I understand that detecting anything more than the very simplest cases may be impossible--I'm thinking of an error similar to the existing "var has no effect in expression" which has helped me catch typos and simple mistakes.
Justin
|
Copyright © 1999-2021 by the D Language Foundation