表达式 x[--i] = y[++i] = z[i++],哪个先计算?

发布于 2024-10-15 19:56:24 字数 671 浏览 3 评论 0原文

当左值的计算先于右值的计算并且赋值也返回一个值时,首先计算以下哪一个?

int i = 2;
int x[] = {1, 2, 3};
int y[] = {4, 5, 6};
int z[] = {7, 8, 9};

x[--i] = y[++i] = z[i++]; // Out of bound exception or not?

注意:通用类 C 语言,左值评估优先。 来自我的教科书

在某些语言中,例如 C, 赋值被认为是一个 运算符的评估,此外 也会产生副作用 返回由此计算的右值。 因此,如果我们用 C 编写:

x = 2;

这样一个命令的评估,在 除了将值 2 赋给 x 之外, 返回值 2。因此,在 C 中, 我们还可以写:

y = x = 2;

应解释为:

(y = (x = 2));

When the evaluation of l-value precedes the evaluation of r-value and the assignment also returns a value, which of the following is evaluated first?

int i = 2;
int x[] = {1, 2, 3};
int y[] = {4, 5, 6};
int z[] = {7, 8, 9};

x[--i] = y[++i] = z[i++]; // Out of bound exception or not?

NOTE: generic C-like language with l-value evaluation coming first. From my textbook:

In some languages, for example C,
assignment is considered to be an
operator whose evaluation, in addition
to producing a side effect, also
returns the r-value thus computed.
Thus, if we write in C:

x = 2;

the evaluation of such a command, in
addition to assigning the value 2 to x,
returns the value 2. Therefore, in C,
we can also write:

y = x = 2;

which should be interpreted as:

(y = (x = 2));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千纸鹤 2024-10-22 19:56:24

我非常确定这种情况下的行为是未定义的,因为您在连续序列点之间多次修改和读取变量 i 的值。

另外,在 C 中,通过将 [] 放在变量名称后面而不是类型后面来声明数组:

int x[] = {1, 2, 3};

编辑:

从示例中删除数组,因为它们[在大多数情况下]不相关。现在考虑以下代码:

int main(void)
{
    int i = 2;
    int x = --i + ++i + i++;
    return x;
}

此代码演示了在原始代码中对变量 i 执行的操作,但没有数组。您可以更清楚地看到变量 i 在此语句中被多次修改。当您依赖在连续序列点之间修改的变量的状态时,行为是未定义的。不同的编译器会(GCC 返回 6,Clang 返回 5)给出不同的结果,并且相同的编译器可以使用不同的优化选项给出不同的结果,或者根本没有明显的原因。

如果此语句没有定义的行为,因为 i 在连续序列点之间被修改了多次,那么对于您的原始代码也可以这样说。赋值运算符不会引入新的序列点。

I'm quite certain that the behaviour in this case is undefined, because you are modifying and reading the value of the variable i multiple times between consecutive sequence points.

Also, in C, arrays are declared by placing the [] after the variable name, not after the type:

int x[] = {1, 2, 3};

Edit:

Remove the arrays from your example, because they are [for the most part] irrelevant. Consider now the following code:

int main(void)
{
    int i = 2;
    int x = --i + ++i + i++;
    return x;
}

This code demonstrates the operations that are performed on the variable i in your original code but without the arrays. You can see more clearly that the variable i is being modified more than once in this statement. When you rely on the state of a variable that is modified between consecutive sequence points, the behaviour is undefined. Different compilers will (and do, GCC returns 6, Clang returns 5) give different results, and the same compiler can give different results with different optimization options, or for no apparent reason at all.

If this statement has no defined behaviour because i is modified several times between comsecutive sequence points, then the same can be said for your original code. The assignment operator does not introduce a new sequence point.

一身骄傲 2024-10-22 19:56:24

一般

在 C 语言中,两个序列点之间的任何操作的顺序不应相互依赖。我不记得标准中的确切措辞,但正是由于这个原因,

i = i++;

这是未定义的行为。该标准定义了组成序列点的事物列表,从内存中看,这是

  1. 语句后面的分号,
  2. 逗号运算符
  3. 在调用函数之前对所有函数参数的求值,
  4. &&和|| operand

查阅维基百科的页面,列表更完整,描述也更详细。序列点是 C 语言中一个极其重要的概念,如果您还不知道它的含义,请立即学习。

具体

无论xyz 变量的求值和赋值顺序定义得多么明确,因为

x[--i] = y[++i] = z[i++];

该语句只能是由于 i--i++i++ 导致未定义的行为。
另一方面

x[i] = y[i] = z[i];

是明确定义的,但我不确定评估顺序的状态。但是,如果这很重要,我宁愿将其分为两个语句以及注释“重要的是......在......之前分配/初始化,因为......”。

General

In C, the order of any operation between two sequence points should not be dependent on. I do not remember the exact wording from the standard, but it is for this reason

i = i++;

is undefined behaviour. The standard defines a list of things that makes up sequence points, from memory this is

  1. the semicolon after a statement
  2. the comma operator
  3. evaluation of all function arguments before the call to the function
  4. the && and || operand

Looking up the page on wikipedia, the lists is more complete and describes more in detail. Sequence points is an extremely important concept in C and if you do not already know what it means, do learn it immediately.

Specific

No matter how well defined the order of evaluation and assignment of the x, y and z variables are, for

x[--i] = y[++i] = z[i++];

this statement cannot be anything but undefined behaviour because of the i--, i++ and i++.
On the other hand

x[i] = y[i] = z[i];

is well defined, but I am not sure what the status for the order of evaluation for this. If this is important however I would rather prefer this to be split into two statements along with a comment "It is important that ... is assigned/initialized before ... because ...".

时常饿 2024-10-22 19:56:24

我认为它与

x[3] = y[4] = z[2];
i = 3;

i think its the same as

x[3] = y[4] = z[2];
i = 3;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文