以下表达式是否未定义行为? [英] Is the following expression undefined behavior ?

查看:80
本文介绍了以下表达式是否未定义行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道以下表达式是否为UB:


i = 2;

x =(i = 3)* i;


因为在C中,评估顺序是未指定的,所以这个表达式是'

''未指定,因为我们不知道哪个操作数首先评估,

(i = 3)或i,那么,x总是6或9吗?取决于评估

订单。


TIA

解决方案

< blockquote>文章< 11 ********************** @ m58g2000cwm.googlegroups .com>,

Neroku< n3 * ***@gmail.com写道:


>我不知道下面的表达式是否为UB:


> i = 2;
x =(i = 3)* i;


>因为在C中,评估顺序未指定,所以此表达式是最少未指定,因为我们不知道不知道哪个操作数首先评估,
(i = 3)或i,那么,x总是6或9吗?视评估顺序而定。



C89(ANSI X3.159-1989)中的相关措辞是,


在前一个和下一个序列点之间一个对象

通过评估

表达式,其存储值最多只能修改一次。此外,只能访问先前值

以确定要存储的值。 [34]


带脚注:


[34]此段落呈现未定义的语句表达式,例如

i = ++ i + 1;

允许

i = i + 1;

这个措辞出现在主标题中,用于描述

运算符,在我的解释中必须被视为等效的

作为约束。但是我们可以更直接地回答这个问题而不需要解释:请注意脚注特别是

表示渲染未定义,因此行为是未定义的。 ,

不仅仅是未指定。

-

法律 - 它是商品

- Andrew Ryan(环球邮报,2005/11/26)


Neroku写道:


>

我不知道下面的表达式是否为UB:


i = 2;

x = (i = 3)* i;


因为在C中,评估顺序未指定,所以此表达式是''

''未指定,因为我们我不知道哪个操作数首先评估,

(i = 3)或i,那么x会不会是6或9?取决于评估

订单。



虽然大多数实现可能会给你一个

值,但UB的定义意味着你无法保证。


考虑一个能够并行运行的平台,生成的代码

包括这两项操作将在

并行执行:


stor 3,i;在我的商店3

mult 3,i,a1;将i乘以3,返回寄存器a1


这可能会产生硬件故障,因为& i可以同时访问和/或
读取和写入时间。

虽然大多数UB例子包括在

序列点之间修改一次项目,如:


i = i ++;



x = i ++ + ++ i;


我相信有问题的UB真的被修改过,并被访问过

用于某些目的,而不是确定要修改的值 (或

类似的措辞),所以以下是UB:


x = i ++ + i;

如果我'我错了(虽然我不相信我),我很确定有人

很快会纠正我。 :-)


-

+ ------------------------ - + -------------------- + ----------------------- +

| Kenneth J. Brody | www.hvcomputer.com | #include |

| kenbrody / at\spamcop.net | www.fptech.com | < std_disclaimer.h |

+ ------------------------- + --------- ----------- + ----------------------- +

不要 - 邮寄给我:< mailto:Th ************* @ gmail.com>


Neroku写道,On 09/02/07 17:51:


我不知道下面的表达式是否为UB:


i = 2;

x =(i = 3)* i;


因为在C中,评估顺序未指定,所以此表达式为''at

至少''未指定,因为我们不知道哪个操作数首先评估,

(i = 3)或i,那么,x是否总是6或9?取决于评估

订单。



此处评估订单不是问题。问题是你读了

" i"除了确定其新值之外的其他原因。所以它是未定义的行为,你可以获得任何价值或崩溃或破坏

流程,因为当它试图同时阅读时会发生总线冲突和

写i。

-

Flash Gordon


I don''t know if the following expression is UB:

i=2;
x = (i=3) * i;

Since in C, evaluation order is unspecified, this expression is ''at
least'' unspecified, since we don''t know which operand evalutes first,
(i=3) or i, So, would x be always 6 or 9 ? depending on the evaluation
order.

TIA

解决方案

In article <11**********************@m58g2000cwm.googlegroups .com>,
Neroku <n3****@gmail.comwrote:

>I don''t know if the following expression is UB:

>i=2;
x = (i=3) * i;

>Since in C, evaluation order is unspecified, this expression is ''at
least'' unspecified, since we don''t know which operand evalutes first,
(i=3) or i, So, would x be always 6 or 9 ? depending on the evaluation
order.

The relevant wording in C89 (ANSI X3.159-1989) is,

Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation of
an expression. Furthermore, the prior value shall be accessed
only to determine the value to be stored. [34]

with footnote:

[34] This paragraph renders undefined statement expressions such as
i = ++i + 1;
while allowing
i = i + 1;
This wording occurs in a main heading for the description of the
operators, and in my interpretation must be treated as equivilent
as a constraint. But we can answer the question more directly without
resorting to interpretations: notice that the footnote specifically
says that "renders undefined", so the behaviour is "undefined",
not merely "unspecified".
--
"law -- it''s a commodity"
-- Andrew Ryan (The Globe and Mail, 2005/11/26)


Neroku wrote:

>
I don''t know if the following expression is UB:

i=2;
x = (i=3) * i;

Since in C, evaluation order is unspecified, this expression is ''at
least'' unspecified, since we don''t know which operand evalutes first,
(i=3) or i, So, would x be always 6 or 9 ? depending on the evaluation
order.

While most implementations will probably give you one of those
values, the definition of UB means that you can''t guarantee it.

Consider a platform capable of parallel operations, and the code
generated includes these two operations to be carried out in
parallel:

stor 3,i ; store 3 in i
mult 3,i,a1 ; multiply i by 3, return in register a1

This could generate a hardware fault, as &i is accessed for both
read and write at the same time.
While most UB examples include modifying an item twice between
sequence points, as in:

i = i++;
or
x = i++ + ++i;

I believe that the UB in question is really "modified, and accessed
for some purpose other than determining the value to modify" (or
similar phrasing), so the following is UB as well:

x = i++ + i;
If I''m wrong (though I don''t believe that I am), I''m sure someone
will correct me shortly. :-)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don''t e-mail me at: <mailto:Th*************@gmail.com>


Neroku wrote, On 09/02/07 17:51:

I don''t know if the following expression is UB:

i=2;
x = (i=3) * i;

Since in C, evaluation order is unspecified, this expression is ''at
least'' unspecified, since we don''t know which operand evalutes first,
(i=3) or i, So, would x be always 6 or 9 ? depending on the evaluation
order.

Evaluation order is not the problem here. The problem is that you read
"i" for a reason other than determining its new value. So it is
undefined behaviour and you could get any value or a crash or wreck the
process due to a bus clash when it tries to simultaneously read and
write "i".
--
Flash Gordon


这篇关于以下表达式是否未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆