如何理解C FAQ 3.8? [英] How to understand C FAQ 3.8?

查看:42
本文介绍了如何理解C FAQ 3.8?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我正在阅读C FAQ的第3部分:
http://www.eskimo.com/~scs/C-faq/top.html


我需要有关问题3.8的更多信息:


==================

3.8:我如何理解这些复杂的表达方式?什么是

序列点?


答:序列点是一个时间点(在
结束时)
评估一个完整的表达式,或者在||,&&,...:或逗号

运算符,或者就在函数调用之前)尘埃
已经结算,所有副作用都保证完整。

ANSI / ISO C标准声明


之间和之后序列点a

对象的表达式应该通过表达式的评估将其存储值修改为



此外,先前值应为被访问

只是为了确定要存储的值。


第二句很难理解。它说

如果一个对象被写入一个完整的表达式,那么任何

以及在同一个表达式中对它的所有访问必须是

计算要写入的值的目的。这个规则

有效地将法律表达限制在那些

访问明显优先于修改之前的那些。


另见下面的问题3.9 。


参考文献:ISO Sec。 5.1.2.3,Sec。 6.3,Sec。 6.6,附件C;

基本原则2.1.2.3; H& S Sec。 7.12.1 pp.228-9。

=========================


我理解法律表达(即:未定义) as:

1)任何变量最多应修改一次。

2)不应引用修改后的变量

其他地方在表达式中。


所以...我可以告诉以下代码是未定义的:


a [i] = i ++;

//我被修改并引用其他地方

//见常见问题3.1。


i ++ * i ++

//我被修改了两次!


但是* p ++怎么样?它是常用的,不应该是未定义的。行为,但p被修改,并且访问了新的

值。


这与我的理解和FAQ 3.2相冲突。

它说post ++只是保证变量

将在表达式完成之前递增,如何
它可以保证p在之前递增*

访问? (即:有没有可能*操作员访问

旧值p)


我不确定我是否已经清楚了。

有人会为我解释一下吗?


谢谢,

mrby

Hi,

I was reading section 3 of the C FAQ:
http://www.eskimo.com/~scs/C-faq/top.html

I need more information about question 3.8:

==================
3.8: How can I understand these complex expressions? What''s a
"sequence point"?

A: A sequence point is a point in time (at the end of the
evaluation of a full expression, or at the ||, &&, ?:, or comma
operators, or just before a function call) at which the dust
has settled and all side effects are guaranteed to be complete.
The ANSI/ISO C Standard states that

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.

The second sentence can be difficult to understand. It says
that if an object is written to within a full expression, any
and all accesses to it within the same expression must be for
the purposes of computing the value to be written. This rule
effectively constrains legal expressions to those in which the
accesses demonstrably precede the modification.

See also question 3.9 below.

References: ISO Sec. 5.1.2.3, Sec. 6.3, Sec. 6.6, Annex C;
Rationale Sec. 2.1.2.3; H&S Sec. 7.12.1 pp. 228-9.
=========================

I understand "a legal expression (i.e: not undefined)" as:
1) Any variable should be modified at most once.
2) The variable modified should not be referenced
"elsewhere" within the expression.

So ... I can tell the following code are undefined:

a[i] = i++;
//i is modified and referenced "elsewhere"
//see FAQ 3.1.

i++*i++
// i is modified twice!

But how about *p++ ? It is commonly used and should not
be "undefined" behavior, but p is modified and the new
value is accessed.

This is conflict with my understanding and with FAQ 3.2.
It said that post ++ merely guarantees that the variable
will be incremented before the expression "finishes", how
can it gurantee that p is incremented right before the *
access? (i.e: Is there the possibility that * operator accesses
the old value of p)

I am not sure I have made myself clear.
Will some guy explain it for me?

Thanks,
mrby

推荐答案

mrby写道:
[来自FAQ的报价,本身引用标准:]
在上一个和下一个序列点之间
对象应该有它的通过表达式的评估,最多只修改一次存储值。
此外,只能访问先前的值,以确定要存储的值。

[...这里FAQ的自己的文字恢复:]
第二句很难理解。它说
如果一个对象被写入一个完整的表达式,那么在同一个表达式中对它的所有访问都必须用于计算要写入的值的目的。这个规则有效地将法律表达限制在
访问明显优先于修改之前的那些。

[...这就是mrby]:
所以......我可以告诉以下代码是未定义的:

a [i] = i ++;
//我被修改并引用其他地方
//见FAQ 3.1。

i ++ * i ++
//我被修改了两次!

但是* p ++怎么样?它是常用的,不应该是未定义的。行为,但p被修改,并访问新的
值。 [...]
[Quotation from the FAQ, itself quoting the Standard:]
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.

[... and here the FAQ''s own text resumes:]
The second sentence can be difficult to understand. It says
that if an object is written to within a full expression, any
and all accesses to it within the same expression must be for
the purposes of computing the value to be written. This rule
effectively constrains legal expressions to those in which the
accesses demonstrably precede the modification.

[... and this is mrby]:
So ... I can tell the following code are undefined:

a[i] = i++;
//i is modified and referenced "elsewhere"
//see FAQ 3.1.

i++*i++
// i is modified twice!

But how about *p++ ? It is commonly used and should not
be "undefined" behavior, but p is modified and the new
value is accessed. [...]




(你的意思是旧的值,我很有信心。)对象'p''

在这里只使用一次,作为`++''运算符的操作数。

表达式'p ++''产生一个值,该值为

*运算符的操作数。 'p ++''不是一个对象,

就像'p + 1''不是一个对象。


只是为了确定值待存储语言

禁止i ++ * i之类的东西。 仅一个变化规则

会允许这样做,但由于我们不知道实际发生的变化实际发生了什么,我们不知道我们会得到什么价值

右手'我'。 (事实上​​,甚至没有保证

'我'将拥有*任何*值;优化者可能会产生

真正奇怪的结果,如非法结构,如这个。)


如果你一丝不苟地区分

一个对象和碰巧占据它的价值

时刻,我想很多你的困惑都会消失。


-
Er ********* @ sun.com



(You mean the "old" value, I''m sure.) The object `p''
is used only once here, as the operand of the `++'' operator.
The expression `p++'' produces a value, and that value is
the operand of the `*'' operator. `p++'' is not an object,
just as `p+1'' is not an object.

The "only to determine the value to be stored" language
prohibits things like `i++ * i''. The "only one change" rule
would permit this, but since we don''t know when the change
actually takes place we don''t know what value we''ll get for
the right-hand `i''. (Indeed, there''s not even a guarantee
that `i'' will have *any* value; optimizers may well generate
truly bizarre results from illegal constructs like this.)

If you are scrupulous in making a distinction between
an object and the value that happens to occupy it at the
moment, I think much of your confusion will disappear.

--
Er*********@sun.com


" ; Eric Sosman
"Eric Sosman"
mrby写道:
[来自FAQ的报价,本身引用标准:]
在上一个和下一个序列点之间
对象应该有通过表达式的评估,其存储值最多被修改一次。
此外,只能访问先前的值,以确定要存储的值。
[...这里是常见问题解答'自己的文本结果mes:]
第二句很难理解。它说
如果一个对象被写入一个完整的表达式,那么在同一个表达式中对它的所有访问都必须用于计算要写入的值的目的。这个规则有效地将法律表达限制在
访问明显优先于修改之前的那些。

[...这就是mrby]:
所以......我可以告诉以下代码是未定义的:

a [i] = i ++;
//我被修改并引用其他地方
//见FAQ 3.1。

i ++ * i ++
//我被修改了两次!

但是* p ++怎么样?它是常用的,不应该是未定义的。行为,但p被修改,并访问新的
值。 [...]
(你的意思是旧的值,我很确定。)对象'p''
在这里只使用一次,作为`++的操作数''运算符。
表达式'p ++''产生一个值,该值是'*''运算符的操作数。 'p ++''不是一个对象,
就像`p + 1''不是一个对象。

只确定要存储的值。语言
禁止i ++ * i之类的东西。 仅一个变化规则
会允许这样做,但由于我们不知道改变何时实际发生,我们不知道我们将获得什么价值
右手?一世''。 (事实上​​,甚至没有保证'我'将拥有*任何*值;优化者可能会产生这样的非法结构真正奇怪的结果。)
mrby wrote:
[Quotation from the FAQ, itself quoting the Standard:]
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.

[... and here the FAQ''s own text resumes:]
The second sentence can be difficult to understand. It says
that if an object is written to within a full expression, any
and all accesses to it within the same expression must be for
the purposes of computing the value to be written. This rule
effectively constrains legal expressions to those in which the
accesses demonstrably precede the modification.

[... and this is mrby]:
So ... I can tell the following code are undefined:

a[i] = i++;
//i is modified and referenced "elsewhere"
//see FAQ 3.1.

i++*i++
// i is modified twice!

But how about *p++ ? It is commonly used and should not
be "undefined" behavior, but p is modified and the new
value is accessed. [...]
(You mean the "old" value, I''m sure.) The object `p''
is used only once here, as the operand of the `++'' operator.
The expression `p++'' produces a value, and that value is
the operand of the `*'' operator. `p++'' is not an object,
just as `p+1'' is not an object.

The "only to determine the value to be stored" language
prohibits things like `i++ * i''. The "only one change" rule
would permit this, but since we don''t know when the change
actually takes place we don''t know what value we''ll get for
the right-hand `i''. (Indeed, there''s not even a guarantee
that `i'' will have *any* value; optimizers may well generate
truly bizarre results from illegal constructs like this.)




你能重新访问上一段的第一句吗? MPJ


如果你一丝不苟地区分一个物品和一个碰巧占据它的价值,我想你的困惑很多将消失。



Can you re-visit the first sentence of the above paragraph? MPJ

If you are scrupulous in making a distinction between
an object and the value that happens to occupy it at the
moment, I think much of your confusion will disappear.



Eric Sosman< er ********* @ sun.com>潦草地写道:
Eric Sosman <er*********@sun.com> scribbled the following:
mrby写道:
[来自FAQ的报价,本身引用标准:]
在前一个和下一个序列点之间通过表达式的评估,对象的存储值最多只能修改一次。
此外,只能访问先前的值,以确定要存储的值。
[...此处常见问题解答'自己的文字简历:]
第二句话很难理解。它说
如果一个对象被写入一个完整的表达式,那么在同一个表达式中对它的所有访问都必须用于计算要写入的值的目的。这个规则有效地将法律表达限制在
访问明显优先于修改之前的那些。

[...这就是mrby]:
所以......我可以告诉以下代码是未定义的:

a [i] = i ++;
//我被修改并引用其他地方
//见FAQ 3.1。

i ++ * i ++
//我被修改了两次!

但是* p ++怎么样?它是常用的,不应该是未定义的。行为,但p被修改,并访问新的
值。 [...]
[Quotation from the FAQ, itself quoting the Standard:]
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.

[... and here the FAQ''s own text resumes:]
The second sentence can be difficult to understand. It says
that if an object is written to within a full expression, any
and all accesses to it within the same expression must be for
the purposes of computing the value to be written. This rule
effectively constrains legal expressions to those in which the
accesses demonstrably precede the modification.

[... and this is mrby]:
So ... I can tell the following code are undefined:

a[i] = i++;
//i is modified and referenced "elsewhere"
//see FAQ 3.1.

i++*i++
// i is modified twice!

But how about *p++ ? It is commonly used and should not
be "undefined" behavior, but p is modified and the new
value is accessed. [...]


(你的意思是旧的值,我很有信心。)对象'p''
在这里只使用一次,作为操作数`++''运算符。
表达式'p ++''产生一个值,该值是'*''运算符的操作数。 `p ++''不是一个对象,
就像`p + 1''不是一个对象。
仅确定要存储的值语言
禁止i ++ * i之类的东西。 仅一个变化规则
会允许这样做,但由于我们不知道改变何时实际发生,我们不知道我们将获得什么价值
右手?一世''。 (事实上​​,甚至没有保证'我'将拥有*任何*价值;优化者可能会产生这样的非法结构真正奇怪的结果。)
如果你一丝不苟地区分一个物体和一个碰巧在它的时刻占据它的价值,我想你的混乱很多就会消失。

(You mean the "old" value, I''m sure.) The object `p''
is used only once here, as the operand of the `++'' operator.
The expression `p++'' produces a value, and that value is
the operand of the `*'' operator. `p++'' is not an object,
just as `p+1'' is not an object. The "only to determine the value to be stored" language
prohibits things like `i++ * i''. The "only one change" rule
would permit this, but since we don''t know when the change
actually takes place we don''t know what value we''ll get for
the right-hand `i''. (Indeed, there''s not even a guarantee
that `i'' will have *any* value; optimizers may well generate
truly bizarre results from illegal constructs like this.) If you are scrupulous in making a distinction between
an object and the value that happens to occupy it at the
moment, I think much of your confusion will disappear.



实际上,如果仅仅修改一个对象并访问它的新值

会导致未定义的行为,那么修改对象将非常可靠

几乎不可能。看看这段代码:


int i = 0;

i = 1;


第二行修改了对象我然后访问它,返回

它的新值1.


-

/ - Joona Palaste(pa *****@cc.helsinki.fi)-------------芬兰-------- \

\ ---- -------------------------------------------------- - 规则! -------- /

人类中的孤雌生殖将导致建立一个新的宗教信仰。

- John Nordberg



Actually, if merely modifying an object and accessing its new value
caused undefined behaviour, modifying objects would be pretty damn
near impossible. Look at this code:

int i=0;
i=1;

The second line modifies the object i and then accesses it, returning
its new value 1.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"Parthenogenetic procreation in humans will result in the founding of a new
religion."
- John Nordberg


这篇关于如何理解C FAQ 3.8?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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