簡體   English   中英

GCC 語句表達式中的執行順序

[英]Execution order in GCC statement expressions

我發現兩個相似的語句之間有不同的執行順序(唯一的區別是下面的語句有一個額外的; )。 析構函數順序不同。 C++ 是否有相應的規范,或者它只是一種未指定的行為?

環境:GCC10

#include <iostream>

template <int num>
struct S {
  S() {std::cout << "S(" << num << ")\n"; }
  ~S() {std::cout << "~S(" << num << ")\n"; }
};

int main() {
  ({S<1>(), S<2>();});
  std::cout << "-----------------------------------\n";
  ({S<3>(), S<4>();;});
}

輸出:

S(1)
S(2)
~S(1)
~S(2)
-----------------------------------
S(3)
S(4)
~S(4)
~S(3)

這不是標准的 C++。 這是稱為語句表達式的 GCC 擴展。 括號中的復合語句可以出現在允許使用表達式的地方。 如果大括號括起來的塊中的最后一條語句是表達式語句,則該表達式的值也是整個語句表達式的值; 否則,語句表達式的類型為void並且沒有值。

你的第一個例子大致相當於

([](){ return S<1>(), S<2>(); })();

(這是一個創建然后立即調用的 lambda)。 有一個逗號表達式可以創建S<1>S<2>臨時變量。 S<1>被銷毀, S<2>從技術上講,被復制到返回值 - 但該副本被省略。 如果不是這個復制省略,你會看到

S<1>()
S<2>()
S<2>(S<2>&&)  // (1) move constructor
~S<2>()  // (2) the original temporary is destroyed
~S<1>()
~S<2>()  // the copy is destroyed outside of the lambda

但是 (1)/(2) 對被省略,留下您在示例中觀察到的序列。

在第二個示例中,大括號內的最后一條語句不是表達式,因此整個內容也沒有值。 它大致相當於

([](){ S<3>(), S<4>(); return; })();

兩個臨時對象都是在 lambda 中創建和銷毀的,通常的規則適用 - 臨時對象以與構造相反的順序銷毀。

暫無
暫無

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

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