1.9 - [intro.execution] - 【總則.執行】

請不要轉載本文;請不要以任何形式重新出版,發佈本文;請在下載本文 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] 上一頁 【總則.對象】 | 下一頁 【總則.鳴謝】
發佈了43 篇原創文章 · 獲贊 1 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章