12

我知道这看起来很熟悉,但它是微软招聘实习生测试中的一个问题。在我看来,这y=++y不符合标准,但我认为确定会更好(不确定我是否比那些在 MS 编写这些测试的人更好)。所以我在征求你的意见。您是否认为这样的表达式符合标准并且不会导致未定义的行为

#include <stdio.h>
int main(){
    int a = 10;
    int b = 10;
    a = ++a;    //What ???
    b = b++;    //What ???
    printf("%d %d\n",a,b);
    return 0;
}

gcc用于编译时抱怨它-Wsequence-point。(没有明确说明它是 C 还是 C++ 特定问题。)

但只提供了四个答案:

a) 10 10
b) 11 10
c) 10 11
d) 11 11

虽然一个不限于只选择一个答案(所以也许我应该选择所有四个?)

好吧,在我看来,自增和赋值之间没有序列点。所以这违反了规范。不是吗?

4

4 回答 4

9

根据 C++11,它们都是定义明确的行为。C++11 甚至没有序列点,因此与序列点相关的警告显然已经过时。赋值运算符对其参数进行排序。

编辑:

虽然每个人都可以同意i = ++i现在是明确定义的行为,但决定i = i++. 直观地说,我应该将其描述为定义明确的,但标准明确指出

i = i++ + 1;

是 UB,我看不出有+ 1什么不同。

简而言之,如果你想回答这个问题,你需要成为绝对不平凡的 C++11 排序规则方面的专家,我似乎不是,但答案似乎是“没有以上是因为UB”。

于 2013-04-08T10:33:37.947 回答
4

根据 C++03 标准,
以下两个语句都会导致未定义的行为

a = ++a;
b = b++;

正如您正确指出的那样,g++ 指出了以下警告:

警告:对“a”的操作可能未定义 [-Wsequence-point]

请注意,在 UB 的情况下,答案可以是 (a)、(b)、(c)、(d) 之外的任何内容。
理想情况下,测试问题中应该有一个“未定义行为”选项。但通常,准备问题的人会简单地在 XYZ 编译器中编译并提交。

这是一个相关的 SO 帖子,解释了Undefined Behavior 和 Sequence Points

于 2013-04-08T10:28:54.490 回答
0

一个=++一个;b= b++; 这些操作被认为是未定义的。每个编译器都可以随心所欲。输出因考官提出问题的编译器而异。

于 2013-04-08T10:34:50.610 回答
-4

我认为是 D) 因为 ++a 表示递增 a 然后执行操作,所以它就像做 a=11。b++ 表示执行操作然后递增,因此您将分配 b=10,但随后 b 递增,使其值为 b=11。

对于纯粹主义者来说,这并不“意味着什么,然后什么”,但这就是它的行为。我对其进行了测试(使用 Visual c++ 和 g++),我的答案是正确的 a=11 和 b=11。

于 2013-04-08T10:31:02.577 回答