编程语言

img lynnboy

1.9 - [intro.execution] - 【总则.执行】

发表于2004/10/29 18:14:00  1131人阅读

分类: ISO/IEC 14882:1998

请不要转载本文;请不要以任何形式重新出版,发布本文;请在下载本文 24 小时内将其删除;禁止将本文用于商业目的。

1 General [intro]

1.9 Program execution [intro.execution]

 

1 总则 【总则】

1.9 程序执行 【总则.执行】

 

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.5)

 

在本国际标准的语义描述中,定义了一个参数化的,非确定的抽象机器。本国际标准不对符合标准的实现的内部结构设置任何约束。实现并不需要复制或模拟这个抽象机器的结构,需要模拟的(仅仅)是下文阐明的抽象机器的可观察的行为。5)

 

Certain aspects and operations of the abstract machine are described in this International Standard as implementation-defined (for example, sizeof(int)). These constitute the parameters of the abstract machine. Each implementation shall include documentation describing its characteristics and behavior in these respects. Such documentation shall define the instance of the abstract machine that corresponds to that implementation (referred to as the “corresponding instance" below).

 

本国际标准将虚拟机器的某些表现和操作描述为实现定义的(如 sizeof(int))。这些就形成了虚拟机器的实现参数。每个实现都应该对它们的具体特性和行为提供文档描述。实现的文档中应当定义对应与该实现的虚拟机器的实例(“对应实例”描述如下)。

 

Certain other aspects and operations of the abstract machine are described in this International Standard as unspecified (for example, order of evaluation of arguments to a function). Where possible, this International Standard defines a set of allowable behaviors. These define the nondeterministic aspects of the abstract machine. An instance of the abstract machine can thus have more than one possible execution sequence for a given program and a given input.

 

本国际标准将虚拟机器的其他一些表现和操作描述为未指明的(如函数参数的求值顺序)。本国际标准在可能的情况下定义一组可采纳的行为。由此定义了抽象机器的非确定性的表现。对于一个已知程序和已知数据,虚拟机器的实例将因其非确定表现而产生不只一个可能的执行序列。

 

Certain other operations are described in this International Standard as undefined (for example, the effect of dereferencing the null pointer). [Note: this International Standard imposes no requirements on the behavior of programs that contain undefined behavior. ]

 

其他操作被本国际标准称为未定义的(如对空指针解进行引用的后果)。【注:本国际标准对包含未定义行为的程序的行为不作任何规范。】

 

A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible execution sequences of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution sequence contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).

 

当一个符合标准的实现执行一个良好形式的程序时,其产生的可观察行为,应该与该实现的抽象机器对应实例依据同一程序和同一输出产生的可能执行序列之一一致。尽管如此,如果在这个执行序列中包含未定义行为,本国际标准仍不会对实现以这个输入数据的这个程序的执行(不包括对第一个未定义操作之前的操作)作任何规范。

 

The observable behavior of the abstract machine is its sequence of reads and writes to volatile data and calls to library I/O functions.6)

 

抽象机器的可观察行为是其对 volatile 数据的读写和对库 I/O 函数的调用的序列。6)

 

Accessing an object designated by a volatile lvalue (3.10), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression might produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.7)

 

访问一个被标为 volatile 左值(3.10)的对象,更改一个对象,调用 I/O 库函数,或调用一个包含任何这类操作的函数的操作都具有副作用,副作用改变了执行环境的状态。表达式的求值可能带来副作用。在被称为序列点的某些执行序列的特定点,所有之前的求值带来的副作用都必须已经完成,所有之后的执行序列的副作用都还没发生。7)

 

Once the execution of a function begins, no expressions from the calling function are evaluated until execution of the called function has completed.8)

 

一旦一个被调用函数开始执行,任何调用者函数中的表达式求值都要等到被调函数完成后进行。8)

 

When the processing of the abstract machine is interrupted by receipt of a signal, the value of objects with type other than volatile sig_atomic_t are unspecified, and the value of any object not of volatile sig_atomic_t that is modified by the handler becomes undefined.

 

当抽象机器的执行由于接收到信号而中断时,除了 volatile sig_atomic_t 以外的任何类型的对象都是未指定的。被信号处理器更改的除 volatile sig_atomic_t 外任何类型的对象的值都将变为未指定的。

 

An instance of each object with automatic storage duration (3.7.2) is associated with each entry into its block. Such an object exists and retains its last-stored value during the execution of the block and while the block is suspended (by a call of a function or receipt of a signal).

 

每个具有自动存储期(3.7.2)的对象实例都与其所在语句块的相应入口相联系。这种对象将在该块的执行期间以及当该块被挂起时一直存在,并总保持其最近保存的值。

 

The least requirements on a conforming implementation are:
  • At sequence points, volatile objects are stable in the sense that previous evaluations are complete and subsequent evaluations have not yet occurred.
  • At program termination, all data written into files shall be identical to one of the possible results that execution of the program according to the abstract semantics would have produced.
  • The input and output dynamics of interactive devices shall take place in such a fashion that prompting messages actually appear prior to a program waiting for input. What constitutes an interactive device is implementation-defined.

[Note: more stringent correspondences between abstract and actual semantics may be defined by each implementation. ]

 

对符合标准的实现的最低要求:
  • 在序列点,volatile 对象之前的求值应该已经完成,其之后的求值应该还未发生,即此 volatile 对象应该是稳定的。
  • 当程序终止时,写入文件的所有数据,应该与抽象语义以此程序执行所能造成的所有可能结果之一吻合。
  • 交互式设备进行输入输出的动态行为应当表现为:在程序进入等待输入之前输出提示性信息。交互式设备的实际构成由实现定义。

注:抽象与实际语义的更严格对应可能由每个实现自行定义。】

 

A full-expression is an expression that is not a subexpression of another expression. If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition.

 

不是其他表达式的子表达式的表达式是完整表达式。如果某语言构成的定义隐含产生对某函数的调用,一个这个语言构成的用例就被认为符合此条定义的意图。

 

[Note: certain contexts in C++ cause the evaluation of a full-expression that results from a syntactic construct other than expression (5.18). For example, in 8.5 one syntax for initializer is
    ( expression-list )
but the resulting construct is a function call upon a constructor function with expression-list as an argument list; such a function call is a full-expression. For example, in 8.5, another syntax for initializer is
    = initializer-clause
but again the resulting construct might be a function call upon a constructor function with one assignment-expression as an argument; again, the function call is a full-expression. ]

 

注:C++ 的特定语境会导致从不是表达式(5.18)的语法构成生成一个完整表达式的执行。例如,8.5 节中的一条初始化符的语法是
    ( 表达式-列表 )
但其所产生的构成可能是对某个构造函数的,以表达式-列表作为参数列表的函数调用;此函数调用就是一个完整表达式。例如,8.5 节中的另一条初始化符的语法是
    = 初始化符-子句
但其所产生的构成仍然可能是对某个构造函数的,以一个赋值-表达式作为参数的调用;此函数调用仍然是一个完整表达式。】

 

[Note: the evaluation of a full-expression can include the evaluation of subexpressions that are not lexically part of the full-expression. For example, subexpressions involved in evaluating default argument expressions (8.3.6) are considered to be created in the expression that calls the function, not the expression that defines the default argument. ]

 

注:完整表达式的求值可能包含对词法上不是完整表达式一部分的子表达式的求值。例如,在默认参数表达式求值中涉及的子表达式,是在调用函数的表达式中创建,而不是定义默认参数的表达式中创建。】

 

[Note: operators can be regrouped according to the usual mathematical rules only where the operators really are associative or commutative.9) For example, in the following fragment
    int a, b;
    /*...*/
    a = a + 32760 + b + 5;

the expression statement behaves exactly the same as
    a = (((a + 32760) + b) + 5);
due to the associativity and precedence of these operators. Thus, the result of the sum (a + 32760) is next added to b, and that result is then added to 5 which results in the value assigned to a. On a machine in which overflows produce an exception and in which the range of values representable by an int is [-32768,+32767], the implementation cannot rewrite this expression as
    a = ((a + b) + 32765);
since if the values for a and b were, respectively, -32754 and -15, the sum a + b would produce an exception while the original expression would not; nor can the expression be rewritten either as
    a = ((a + 32765) + b);
or
    a = (a + (b + 32765));
since the values for a and b might have been, respectively, 4 and -8 or -17 and 12. However on a machine in which overflows do not produce an exception and in which the results of overflows are reversible, the above expression statement can be rewritten by the implementation in any of the above ways because the same result will occur. ]

 

【注:仅当运算符真正具有结合性或交换性时,才能根据数学管理规则进行重新分组。9) 例如,在如下片段中
    int a, b;
    /*...*/
    a = a + 32760 + b + 5;

根据运算符的结合性和优先级,表达式语句实际表现为
    a = (((a + 32760) + b) + 5);
由此,和 (a + 32760) 的结果接着与 b 相加,然后把此结果再加上 5 后的结果值赋值给 a。如果一台机器对溢出产生异常,并且它的 int 取值范围是 [-32768,32767],则在其上的实现不能把表达式按
    a = ((a + b) + 23765);
重写,因为如果 ab 的值分别为 -32754 和 -15,则 a + b 的和就会导致一个异常,而原来的表达式却不会;表达式也不能按
    a = ((a + 32765) + b);

    a = (a + (b + 32765));
重写,因为也许 ab 的值就分别是 4 和 -8,或 -17 和 12。 然而在一个溢出不产生异常,并且溢出的结果可逆的机器上,上述的表达式语句就可以被实现以上面的任何方式重写,因为它们产生相同的结果。】

 

There is a sequence point at the completion of evaluation of each full-expression10).

 

每个完整表达式求值完成的地方是一个序列点10)

 

When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body. There is also a sequence point after the copying of a returned value and before the execution of any expressions outside the function11). Several contexts in C++ cause evaluation of a function call, even though no corresponding function call syntax appears in the translation unit. [Example: evaluation of a new expression invokes one or more allocation and constructor functions; see 5.3.4. For another example, invocation of a conversion function (12.3.2) can arise in contexts in which no function call syntax appears. ] The sequence points at function-entry and function-exit (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.

 

当调用一个函数时(无论函数是否内联),所有函数参数(如果有)的求值之后是一个序列点,并出现在函数体中的任何表达式或语句执行之前。在复制返回值之后和函数之外的任何语句执行之前也有一个序列点11)。在某些 C++ 的语境中,即使在翻译单元中没有出项与其相对应的语法,也会导致函数调用的执行。【例:new 表达式的求值会执行至少一个存储分配和构造函数;参见 5.3.4。又例如,不包含函数调用语法的语境可能导致类型转换函数(12.3.2)的执行。】无论调用函数的表达式语法如何,在函数入口和函数出口(如上所述)的序列点都是函数调用被求值时的特性。

 

In the evaluation of each of the expressions
    a && b
    a || b
    a ? b : c
    a , b

using the built-in meaning of the operators in these expressions (5.14, 5.15, 5.16, 5.18), there is a sequence point after the evaluation of the first expression12).

 

对表达式
    a && b
    a || b
    a ? b : c
    a , b

使用其中运算符的内建意义求值时(5.14,5.15,5.16,5.18),其中第一个表达式求值后为一个序列点。12)

 

5) This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.

 

5) 这个条款往往被称为“好像”原则,因为只要实现的结果通过考察程序的可观察行为可被认为好像是遵从了本国际标准的规格时,实现就可以自由忽略任何规格。例如,如果某个具体实现可以推导出表达式中的某部分的值不会被用到,并且这一部分表达式的副作用不会对程序产生的可观察行为造成影响时,这个实现就无需对这部分表达式进行求值。

 

6) An implementation can offer additional library I/O functions as an extension. Implementation that do so should treat calls to those functions as “observable behavior” as well.

 

6) 实现可以提供额外的 I/O 库函数作为扩展,实现应该把对这些函数的调用同样看作“可观察行为”。

 

7) Note that some aspects of sequencing in the abstract machine are unspecified; the preceding restriction upon side effects applies to that particular execution sequence in which the actual code is generated. Also note that when a call to a library I/O function returns, the side effect is considered complete, even though some external actions implied by the call (such as the I/O itself) may not have completed yet.

 

7) 注意,某些情况下抽象机器执行的次序是未指定的;上述有关副作用的限制适用于那些生成实际代码的执行序列。还要注意,当从 I/O 库函数调用返回时,即使这个函数调用执行的某些外部动作(比如硬件 I/O 动作本身)还没完成,这个函数调用的副作用仍然被认为是完成的。

 

8) In other words, function executions do not interleave with each other.

 

8) 也就是说,函数的执行不会互相交叉。

 

9) Overloaded operators are never assumed to be associative or commutative.

 

9) 重载的运算符总不具有结合性或交换性。

 

10) As specified in 12.2, after the “end-of-full-expression” sequence point, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.

 

10) 12.2 节中规定,“完整表达式结尾”的序列点之后,以通常与每个临时对象的构造顺序相反的顺序,执行零或多个临时对象的析构函数调用的序列。

 

11) The sequence point at the function return is not explicitly specified in ISO C, and can be considered redundant with sequence points at full-expressions, but the extra clarity is important in C++. In C++, there are more ways in which a called function can terminate its execution, such as the throw of an expression.

 

11) 函数返回处的序列点没有被 ISO C 明确指定,并在完整表达式的序列点中是多余的,但在 C++ 中对之澄清却很重要。C++ 中,被调函数有更多的终止执行的方式,如抛出一个表达式。

 

12) The operators indicated in this paragraph are the built-in operators, as described in clause 5. When one of these operators is overloaded (clause 13) in a valid context, thus designating a user-defined operator function, the expression designates a function invocation, and the operands form an argument list, without an implied sequence point between them.

 

12) 此段落指示的运算符是在第 5 章中描述的内建运算符。若某运算符在合法语境中被重载(章节 13),就指定了一个用户定义的运算符函数,此表达式标明了一个函数调用,并由其操作数构成参数表,而不会在其之间暗指序列点。

 

PREV [intro.object] | NEXT [intro.ack] 上一页 【总则.对象】 | 下一页 【总则.鸣谢】
阅读全文
0 0

相关文章推荐

img
取 消
img