这是 C++ 中未定义的行为吗?
我想知道下面最后一个 if 中对 x 的访问是否是未定义的行为:
int f(int *x)
{
*x = 1;
return 1;
}
int x = 0;
if (f(&x) && x == 1) {
// something
}
I was wondering whether the access to x in the last if below here is undefined behaviour or not:
int f(int *x)
{
*x = 1;
return 1;
}
int x = 0;
if (f(&x) && x == 1) {
// something
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
它不是未定义的行为,因为运算符
&&
是一个序列点It's not undefined behavior as operator
&&
is a sequence point它有明确的定义。
参考 - C++03 标准:
第 5 节:表达式,第 4 段:
期间,
It is well defined.
Reference - C++03 Standard:
Section 5: Expressions, Para 4:
While in,
它被定义了。 C/C++ 进行惰性求值,并定义首先计算并检查左表达式。如果这是真的,那么就是正确的。
It is defined. C/C++ do lazy evaluation and it is defined that first the left expression will be calculated and checked. If it is true then the right one will be.
不可以,因为
&&
定义了一种顺序,其中左轴必须在右轴之前计算。||
、?:
和,
上也有定义的顺序。其他操作数上没有。在可比较中:
那么它是未定义的。此处,左侧和右侧都将按任意顺序进行计算。这种逻辑的非捷径形式不太常见,因为捷径通常被认为至少对性能有益,而且通常对正确性至关重要。
No, because
&&
defines an ordering in which the lhs must be computed before the rhs.There is a defined order also on
||
,?:
and,
. There is not on other operands.In the comparable:
Then it's undefined. Here both the lhs and rhs will be computed and in either order. This non-shortcutting form of logical and is less common because the short-cutting is normally seen as at least beneficial to performance and often vital to correctness.
这不是未定义的行为。原因取决于两个事实,两者都足以给出定义的行为
下面也是定义的行为
但是,您不知道
x == 1
的计算结果是true
还是false
,因为&
的第一个或第二个操作数可以首先被评估。不过,这对于定义此代码的行为并不重要。It is not undefined behavior. The reason depends on two facts, both are sufficient for giving defined behavior
The following is defined behavior too
However, you don't know whether
x == 1
evaluates totrue
orfalse
, because either the first or the second operand of&
can be evaluated first. That's not important for the behavior of this code to be defined, though.它不是未定义的,但也不应该编译,因为您试图将指向 x (
&x
) 的指针分配给引用。&&
将从左到右进行计算(如果左侧计算结果为 false,则计算将停止)。编辑:通过更改,它应该可以编译,但仍然会被定义(因为如果您使用指针或引用并不重要)。
It's not undefined, but it shouldn't compile either, as you're trying to assign a pointer to x (
&x
) to a reference.&&
will be evaluated from left to right (evaluation will stop, if the left side evaluates false).Edit: With the change it should compile, but will still be defined (as it doesn't really matter if you use a pointer or reference).
它将调用者块中局部变量x的地址作为参数传递给f(指向int的指针)。然后 f 会将参数(这是堆栈上的临时变量)设置为地址 1(这不会导致问题)并返回 1。由于 1 为 true,因此 if () 将继续评估 x == 1,结果为 false ,因为主块中的x仍然是0。if
块的主体不会被执行。
编辑
对于问题的新版本,主体将被执行,因为 f() 返回后,调用块中的 x 为 1。
It will pass the address of the local variable x in the caller block as a parameter to f (pointer to int). f will then set the parameter (which is a temporary variable on the stack) to address 1 (this causes no problem) and return 1. Since 1 is true, the if () will move on to evaluate x == 1 which is false, because x in the main block is still 0.
The body of the if block will not be executed.
EDIT
With your new version of the question, the body will be executed, because after f() has returned, x in the calling block is 1.