Why can't I do ++i++ in C-like languages?

為{幸葍}努か 提交于 2019-11-27 01:47:16

问题


Half jokingly half serious : Why can't I do ++i++ in C-like languages, specifically in C#?

I'd expect it to increment the value, use that in my expression, then increment again.


回答1:


Short answer: i++ is not an "lvalue", so can't be the subject of an assignment.




回答2:


Though the short answer "it's not an lvalue" is correct, that's perhaps just begging the question. Why isn't it an lvalue? Or, as we say in C#, a variable.

The reason is because you cannot have your cake and eat it too. Work it out logically:

First off, the meaning of a ++ operator in C#, whether postfix or prefix, is "take the value of this variable, increment the value, assign the new value to the variable, and produce a value as a result". The value produced as the result is either the original value or the incremented value, depending on whether it was a postfix or a prefix. But either way, you produce a value.

Second, the value of a variable is always the current contents of that variable. (Modulo certain bizarre threading scenarios that would take us far afield.)

I hope you agree that these are perfectly sensible rules.

Now it should be clear why the result of i++ cannot be a variable, but in case it isn't, let me make it clear:

Suppose i is 10. The meaning of i++ should be "get the value of i — 10 — increment it — 11 — store it — i is now 11 — and give the original value as the result — 10". So when you say print(i++) it should print 10, and 11 should be stored in i.

Now suppose the meaning of i++ is to return the variable, not the value. You say print(i++) and what happens? You get the value of i — 10 — increment it — 11 — store it — i is now 11 — and give the variable back as a result. What's the current value of the variable? 11! Which is exactly what you DON'T want to print.

In short, if i++ returned a variable then it would be doing exactly the opposite of the intended meaning of the operator! Your proposal is logically inconsistent, which is why no language does it that way.




回答3:


Because you care about a next programmer maintaining (or trying to re-write)your code, long after you're fired for defying popular conventions.




回答4:


I tested (++i,i++) as a workaround:

#include <stdio.h> 

int main(){
  int i=0;

  printf(" i:         %i\n", i         );
  printf(" (++i,i++): %i\n", (++i,i++) );
  printf(" i:         %i\n", i         );
}

Result:


i:         0
(++i,i++): 1
i:         2



回答5:


Because the result of i++ isn't an lvalue.




回答6:


I believe that the increment(or decrement) operator needs an lvalue to assign to. However ++i is not an lvalue, it's an expression. Someone better versed in compilers might be able to clarify if there is any technical reason for this constraint.




回答7:


From section 7.5.9 of the C# 3.0 specification:

The operand of a postfix increment or decrement operation must be an expression classified as a variable, a property access, or an indexer access. The result of the operation is a value of the same type as the operand. If the operand of a postfix increment or decrement operation is a property or indexer access, the property or indexer must have both a get and a set accessor. If this is not the case, a compile-time error occurs.

Additionally, the post-increment expression (i++) would be evaluated first because it has a higher precedence than the pre-increment (++i) operator.



来源:https://stackoverflow.com/questions/1511082/why-cant-i-do-i-in-c-like-languages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!