2

可能重复:
未定义的行为和序列点

我正在使用 Microsoft Visual C++。看下面的例子:

int n = 5;
char *str = new char[32];
strcpy(str, "hello world");
memcpy(&str[n], &str[n+1], 6+n--);
printf(str);
// output is "hell world"

所以出乎意料的是,我的编译器生成的代码首先递减 n,然后执行 memcpy。以下来源将做我期望发生的事情:

int n = 5;
char *str = new char[32];
strcpy(str, "hello world");
memcpy(&str[n], &str[n+1], 6+n);
n--;
printf(str);
// output is "helloworld"

首先,我试图向自己解释。最后一个参数首先被压入堆栈,因此可以先评估它。但我真的相信在下一个分号之后评估后递增/递减保证。

所以我进行了以下测试:

void foo(int first, int second) {
    printf("first: %i / second: %i", first, second);
}
int n = 10;
foo(n, n--);

这将输出“第一:10 / 第二:10”。

所以我的问题是:这种情况是否有任何明确的行为?有人可以指出我描述的文件吗?有没有发现编译器的bug~~OO~~?

该示例已简化为不再有意义,它只是说明了我的问题并且可以自行运行。

4

1 回答 1

7

有两个相关的问题在起作用。首先,函数参数的执行顺序是未指定的。保证的是在进入函数体之前所有的都被执行。其次,这是未定义的行为,因为您正在更改和阅读n这些表达式之间没有任何序列点。

于 2013-02-04T21:11:57.987 回答