簡體   English   中英

C++ 語言解析和邏輯運算符的短路

[英]C++ Language Parsing and Logical Operators's Short-Circuit

當涉及到邏輯運算符的短路時,根據 7.6.14 e 7.6.15 (N4868) 中的標准。

7.6.14 邏輯與運算符

[...] 如果第一個操作數為假,則不會評估第二個操作數。

7.6.15 邏輯或運算符

[...] 如果第一個操作數的計算結果為真,則不會計算第二個操作數。

當此實現在邏輯運算符鏈接中討論為 (Cond1 && Cond2 && Cond3) 時,在我的解釋中,所呈現的與我目前的心理 model不同,關於 c++ 代碼解析/運算符綁定如何發生在編譯器時

對於某些東西

if (cond1 && cond2 && cond3) {
   //something
}

理解為“如果cond1為假,則發生短路,cond2和cond3不求值,表達式為假”

對我來說,即使你有相同的結果,關於解析應該如何工作的更准確的表達是“第一個'AND'操作是第二個的子表達式。如果 cond1 為假,則發生短路,cond2不計算,子表達式被計算為假。然后在第二個操作中發生短路,cond3 沒有被計算,這個表達式也被計算為假”。

喜歡:

(cond1 && cond2) && cond3: 評估 cond1 並將子表達式短路為 false (不評估 cond2)

false && cond3:將完整表達式短路為 false(未評估 cond3)


我擔心像 C ++ 這樣的高級語言中的 model 而不是運行時的實現(編譯器的實現似乎與我展示的第一個表達式完全相同,如果 cond1 為 false 則發生跳轉)。

我所做的解釋是准確的,迂腐的還是不正確的,在這種情況下不合適(這是過度思考)?

就編譯器的“心理模型”而言,您是正確的,而在這種特定情況下,就 CPU 的“心理模型”而言,寫“如果cond1為假,則完整表達式為false ”的人是正確的。

在編譯器方面,解析cond1 && cond2 && cond3結果(使用 clang -ast-dump

`-BinaryOperator 0x557a79f02230 <col:1, col:19> 'bool' '&&'
  |-BinaryOperator 0x557a79f021d8 <col:1, col:10> 'bool' '&&'
  | |-ImplicitCastExpr 0x557a79f021a8 <col:1> 'bool' <LValueToRValue>
  | | `-DeclRefExpr 0x557a79f02168 <col:1> 'bool' lvalue Var 0x557a79f01da0 'cond1' 'bool'
  | `-ImplicitCastExpr 0x557a79f021c0 <col:10> 'bool' <LValueToRValue>
  |   `-DeclRefExpr 0x557a79f02188 <col:10> 'bool' lvalue Var 0x557a79f01ec8 'cond2' 'bool'
  `-ImplicitCastExpr 0x557a79f02218 <col:19> 'bool' <LValueToRValue>
    `-DeclRefExpr 0x557a79f021f8 <col:19> 'bool' lvalue Var 0x557a79f01fa8 'cond3' 'bool'

對這棵樹的評估從第 19 列的根&&開始,它必須首先評估它的 lhs: 所以它走到第 10 列的&& ,它也必須首先評估它的 lhs: 所以它走到cond1 如果返回false , col:10 &&也返回false ,而不訪問 rhs 分支,然后 col:19 &&也返回false而不訪問 rhs 分支。

我剛剛測試的 gcc 和 clang 都生成了相當於

if (cond1 == false) goto done;
if (cond2 == false) goto done;
if (cond3 == false) goto done;
 return true;
done:
 return false;

所以這個評估是一個(非常簡單的)編譯器優化的例子

有關 AST 和編譯代碼,請參見https://godbolt.org/z/rYc11PvPb

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM