逗号运算符没有副作用吗?
例如,对于这样的语句:
c += 2, c -= 1
c += 2 是否总是首先被求值,并且第二个表达式 c-= 1 中的 c 是否总是从表达式 c += 2 更新值?
For example for such statement:
c += 2, c -= 1
Is it true that c += 2 will be always evaluated first, and c in second expression c-= 1 will always be updated value from expression c += 2?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,只要该逗号是非重载的逗号运算符,它就受到标准的保证。引用 n3290 §5.18:
以及相应的脚注:
因此,这仅适用于非重载的逗号运算符。
函数参数之间的
,
不是逗号运算符。这条规则在那里也不适用。对于C++03,情况类似:
但限制是相同的:不适用于重载的逗号运算符或函数参数列表。
Yes, it is guaranteed by the standard, as long as that comma is a non-overloaded comma operator. Quoting n3290 §5.18:
And the corresponding footnote:
So this holds only for the non-overloaded comma operator.
The
,
between arguments to a function are not comma operators. This rule does not apply there either.For C++03, the situation is similar:
Restrictions are the same though: does not apply to overloaded comma operators, or function argument lists.
是的,逗号运算符保证语句按从左到右的顺序计算,并且返回值是计算的最右边的语句。
但请注意,某些上下文中的逗号不是逗号运算符。例如,对于函数参数列表,不能保证上述情况。
Yes, the comma operator guarantees that the statements are evaluated in left-to-right order, and the returned value is the evaluated rightmost statement.
Be aware, however, that the comma in some contexts is not the comma operator. For example, the above is not guaranteed for function argument lists.
是的,在 C++ 中,逗号运算符是一个序列点,这些表达式将按照它们的写入顺序进行计算。请参阅当前工作草案中的
5.18
:我觉得你的问题缺乏对“副作用”含义的解释。 C++ 中的每个语句都允许有副作用,重载的逗号运算符也是如此。
为什么你写的语句在函数调用中无效?
这都是关于序列点的。在 C++ 和 C 中,禁止在两个序列点之间修改两次值。如果您的示例真正使用
运算符
,则每个自分配都位于其自己的序列点内。如果您像这样使用它foo(c += 2, c -= 2)
则评估顺序是未定义的。我实际上不确定第二种情况是否是未定义的行为,因为我不知道参数列表是一个还是多个序列点。我应该问这个问题。Yes, in C++ the comma operator is a sequence point and those expression will be evaluated in the order they are written. See
5.18
in the current working draft:I feel that your question is lacking some explanation as to what you mean by "side effects". Every statement in C++ is allowed to have a side effect and so is an overloaded comma operator.
Why is the statement you have written not valid in a function call?
It's all about sequence points. In C++ and C it is forbidden to modify a value twice inside between two sequence points. If your example truly uses
operator,
every self-assignment is inside its own sequence point. If you use it like thisfoo(c += 2, c -= 2)
the order of evaluation is undefined. I'm actually unsure if the second case is undefined behaviour as I do not know if an argument list is one or many sequence points. I ought to ask a question about this.它应该始终从左到右计算,因为这是逗号运算符的定义:
链接
It should be always evaluated from left to right, as this is the in the definition of the comma operator:
Link
你有两个问题。
第一个问题:“逗号运算符没有副作用吗?”
答案是否定的。逗号运算符自然有利于编写具有副作用的表达式,而故意编写具有副作用的表达式正是该运算符的常用用途。例如,在 while (cin >> str, str != "exit") 中,输入流的状态发生了改变,这是有意的副作用。
但也许你并不是指计算机科学意义上的副作用,而是某种特殊意义上的副作用。
你的第二个问题:“例如,对于这样的语句:
c += 2, c -= 1
是否总是先计算 c += 2,然后在第二个表达式 c-= 1 中计算 c总是会从表达式 c += 2 更新值?”对于语句或表达式,答案是肯定的,除非逗号运算符被重载(非常不寻常)。但是,像
c += 2, c -= 1
这样的序列也可以出现在参数列表中,在这种情况下,您得到的不是表达式,逗号也不是序列运算符,并且评估的顺序没有定义。在foo(c += 2, c -= 1)
中,逗号不是逗号运算符,但在foo((c += 2, c -= 1))
中> 是的,所以可能要注意函数调用中的括号。You've got two questions.
The first question: "Is comma operator free from side effect?"
The answer to this is no. The comma operator naturally facilitates writing expressions with side effects, and deliberately writing expressions with side effects is what the operator is commonly used for. E.g., in
while (cin >> str, str != "exit")
the state of the input stream is changed, which is an intentional side effect.But maybe you don't mean side-effect in the computer science sense, but in some ad hoc sense.
Your second question: "For example for such statement:
c += 2, c -= 1
Is it true that c += 2 will be always evaluated first, and c in second expression c-= 1 will always be updated value from expression c += 2?"The answer to this is yes in the case of a statement or expression, except when the comma operator is overloaded (very unusual). However, sequences like
c += 2, c -= 1
can also occur in argument lists, in which case, what you've got is not an expression, and the comma is not a sequence operator, and the order of evaluation is not defined. Infoo(c += 2, c -= 1)
the comma is not a comma operator, but infoo((c += 2, c -= 1))
it is, so it may pay to pay attention to the parentheses in function calls.