[英]What exactly is the “as-if” rule?
正如標題所說:
人們會得到的典型答案是:
允許任何和所有不改變程序可觀察行為的代碼轉換的規則
有時,我們會不斷從某些實現中獲取行為,這歸因於此規則。 錯了很多次。
那么,這個規則究竟是什么? 標准沒有明確地將此規則作為一個部分或段落提及,那么該規則的權限范圍究竟是什么?
對我來說,這似乎是一個標准沒有詳細定義的灰色區域。 有人可以詳細說明細節,引用標准中的參考資料嗎?
注意:將其標記為 C 和 C++,因為它與兩種語言都相關。
“ as-if ”規則基本上定義了允許實現對合法 C++ 程序執行的轉換。 簡而言之,所有不影響程序“可觀察行為”的轉換(請參見下面的精確定義)都是允許的。
目標是讓實現可以自由地執行優化,只要程序的行為仍然符合 C++ 標准在抽象機器方面指定的語義。
C++11 標准在第 1.9/1 段中引入了“ as-if ”規則:
本國際標准中的語義描述定義了一個參數化的非確定性抽象機器。 本國際標准對符合性實現的結構沒有要求。 特別是,他們不需要復制或模擬抽象機器的結構。 相反,符合要求的實現需要模擬(僅)抽象機的可觀察行為,如下所述。
此外,一個解釋性腳注補充說:
該規定有時被稱為“好像”規則,因為只要從可觀察到的行為可以確定的結果是好像要求已被遵守,實施就可以自由地無視本國際標准的任何要求的程序。 例如,如果一個實際的實現可以推斷出它的值沒有被使用並且沒有產生影響程序可觀察行為的副作用,那么它就不需要評估表達式的一部分。
第 1.9/5 段進一步規定:
執行格式良好的程序的符合實現應產生與具有相同程序和相同輸入的抽象機的相應實例的可能執行之一相同的可觀察行為。 但是,如果任何此類執行包含未定義的操作,則本國際標准對使用該輸入執行該程序的實現沒有要求(甚至不要求第一個未定義操作之前的操作)。
值得強調的是,此約束僅適用於“執行格式良好的程序” ,並且執行包含未定義行為的程序的可能結果是不受約束的。 這在第 1.9/4 段中也有明確說明:
本國際標准中將某些其他操作描述為未定義(例如,嘗試修改 const 對象的效果)。 [注意:本國際標准對包含未定義行為的程序的行為沒有要求。 ——尾注]
最后,關於“可觀察行為”的定義,第1.9/8段如下:
對一致實現的最低要求是:
— 對 volatile 對象的訪問嚴格按照抽象機的規則進行評估。
— 在程序終止時,寫入文件的所有數據應與根據抽象語義執行程序可能產生的結果之一相同。
— 交互設備的輸入和輸出動態應以這樣一種方式發生,即在程序等待輸入之前實際傳送提示輸出。 什么構成交互設備是實現定義的。
這些統稱為程序的可觀察行為。 [注意:抽象語義和實際語義之間更嚴格的對應關系可能由每個實現定義。 —尾注]
據我所知,“ as-if ”規則的唯一例外是復制/移動省略,即使類的復制構造函數、移動構造函數或析構函數具有副作用,也允許這樣做。 第 12.8/31 段規定了具體條件:
當滿足某些條件時,允許實現省略類對象的復制/移動構造,即使為復制/移動操作選擇的構造函數和/或對象的析構函數有副作用。 [...]
在 C11 中,規則永遠不會被稱為該名稱。 然而,C 就像 C++ 一樣,根據抽象機器定義行為。 as-if 規則在C11 5.1.2.3p4 和 p6 中:
在抽象機中,所有表達式都按照語義指定的方式進行評估。 如果一個實際的實現可以推斷出它的值未被使用並且沒有產生所需的副作用(包括由調用函數或訪問易失性對象引起的任何副作用),則它不需要計算表達式的一部分。
[...]
對一致實現的最低要求是:
- 對
volatile
對象的訪問嚴格按照抽象機的規則進行評估。- 在程序終止時,寫入文件的所有數據應與根據抽象語義執行程序所產生的結果相同。
- 交互設備的輸入和輸出動態應按照7.21.3 的規定進行。 這些要求的目的是盡快出現無緩沖或行緩沖的輸出,以確保在程序等待輸入之前實際出現提示消息。
這是程序的可觀察行為。
在 C、C++、Ada、Java、SML 中……在任何編程語言中,通過描述程序的(通常是許多可能的、非確定性的)行為(暴露於 I/O 端口上的一系列交互)來很好地指定,沒有明顯的 as-if 規則。
獨特規則的一個例子是,除以零引發異常(Ada、Caml)或空引用引發異常(Java)。 您可以更改規則以指定其他內容,最終會使用不同的語言(有些人寧願稱之為“方言”(*)。不同的規則是指定編程語言的一些不同用途,例如不同的語法規則涵蓋了一些語法結構。
(*) 根據一些語言學家的說法,方言是一種帶有“軍隊”的語言。 在這種情況下,這可能意味着一種沒有委員會和特定編譯器編輯行業的編程語言。
as-if 規則不是一個獨特的規則; 它沒有特別涵蓋任何程序,甚至不是可以以任何方式討論、刪除或更改的規則:所謂的“規則”只是重申程序語義已定義,並且只能是可移植的(通用)根據程序執行與“外部”世界的可見交互來定義。
外部世界可以是 I/O 接口 (stdio)、GUI,甚至是輸出純應用語言的結果值的交互式解釋器。 在 C 和 C++ 中,包括對易失性對象的(含糊地指定的)訪問,這是另一種說法,即必須嚴格根據 ABI(應用程序二進制接口)在內存中表示給定點的某些對象,而從未明確提及 ABI。
執行痕跡的定義,也稱為可見或可觀察的行為,定義了“as-if 規則”的含義。 as-if 規則試圖解釋它,但通過這樣做,它使人們感到困惑而不是澄清事情,因為它表達了作為附加語義規則的表達,為實現提供了更多的余地。
概括:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.