首頁  >  文章  >  後端開發  >  將常數參考綁定到 C 中的臨時子物件是錯誤還是預期行為?

將常數參考綁定到 C 中的臨時子物件是錯誤還是預期行為?

Linda Hamilton
Linda Hamilton原創
2024-10-26 11:26:29822瀏覽

Is Binding a Const Reference to a Temporary Sub-Object in C   a Bug or Expected Behavior?

將常數引用綁定到臨時子物件:一個難題

下面的C 程式碼片段示範了不同編譯器之間的行為差異當嘗試將const 引用綁定到臨時物件的子物件時:

<code class="cpp">#include <stdio.h>

struct P2d {
    double x, y;
    P2d(double x, double y) : x(x), y(y) {}
    ~P2d() { printf("Destructor called\n"); }
};

P2d center() {
    return P2d(10, 10);
}

int main(int argc, const char *argv[]) {
    const double& x = center().x;  // Bind a reference to temporary's x member
    printf("x = %.18g\n", x); // Expected: 10
    return 0;
}</code>

錯誤或預期行為?

像 g 這樣的編譯器會終止該物件的生命週期在 main 中輸入 printf 之前的臨時 P2d 實例,但雙成員 x 的值仍然保留。這是透過建立另一個臨時雙精度值來複製值而不是綁定到原始臨時的成員來實現的。

另一方面,clang 正確地延長了 P2d 臨時的生命週期以匹配 x 引用的生命週期,從而允許main 中 printf 之後調用的析構函數。

這個差異提出了一個問題: g 的行為是錯誤還是在 C 標準下是允許的?

分析與解

CWG 1651 闡明了這個問題:


將引用綁定到子物件不應延長臨時物件的生命週期。


在目前標準下,標量以外的物件(例如類別或陣列)可以延長臨時物件的生命週期。

編譯器行為

  • GCC:根據 CWG 1651 決議,僅延長類別或陣列子物件的生命週期。
  • Clang:已經實現了 N3918 中概述的生命週期延長規則,這延長了所有臨時子物件的生命週期。

結論

基於C 標準的當前措辭,GCC 的行為在技術上是正確的,而Clang 的實現反映了DR 1651 中提議的更改。將來很可能會修訂該標準以反映此變更。

以上是將常數參考綁定到 C 中的臨時子物件是錯誤還是預期行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn