簡體   English   中英

這個C ++靜態分析規則是否有意義?

[英]Does this C++ static analysis rule make sense as is?

我正在實現一些C ++靜態分析規則,其中一個規則禁止函數返回引用或指向函數引用參數的指針,即以下都是不兼容的:

int *f(int& x) { return &x; } // #1
const int *g(const int& x) { return &x; } // #2
int& h(int& x) { return x; } // #3
const int& m(const int& x) { return x; } // #4

為此給出的理由是“它是實現定義的行為,無論引用參數是臨時對象還是對參數的引用”。

然而,我對此感到困惑,因為C ++中的流操作符是以這種方式編寫的,例如

std::ostream& operator<<(std::ostream& os, const X& x) {
    //...
    return os;
}

我認為我非常有信心C ++中的流操作符通常不會表現出實現定義的行為,所以發生了什么?

根據我目前的理解,我希望#1和#3能夠很好地定義,因為temporaries不能綁定到非const引用,所以int& x指的是一個超出生命周期的真實對象函數的范圍,因此返回指向該對象的指針或引用是好的。 我希望#2是狡猾的,因為臨時可能已經綁定到const int& x ,在這種情況下嘗試獲取其地址似乎是一個糟糕的計划。 我不確定#4 - 我的直覺是,這也可能是狡猾的,但我不確定。 特別是,我不清楚以下情況會發生什么:

const int& m(const int& x) { return x; }
//...
const int& r = m(23);

正如你所說,#1和#3都很好(雖然#1可以說是糟糕的風格)。

#4是出於同樣的原因而狡猾#2是; 它允許將const引用傳播到其生命周期的臨時值。

讓我們檢查:

#include <iostream>

struct C {
  C() { std::cout << "C()\n"; }
  ~C() { std::cout << "~C()\n"; }
  C(const C &) { std::cout << "C(const C &)\n"; }
};

const C &foo(const C &c) { return c; }

int main() { 
   const C &c = foo(C());
   std::cout << "c in scope\n";
}

這輸出:

C()
~C()
c in scope

在C ++ 11中,如果還存在右值引用過載,則可以使#2和#4安全。 從而:

const int *get( const int &x ) { return &x; }
const int *get( const int &&x ) { return nullptr; }

void test() {
    const int x = 0;
    const int *p1 = get( x ); // OK; p1 is &x.
    const int *p2 = get( x+42 ); // OK; p2 is nullptr.
}

因此,盡管它們很狡猾,但如果程序員知道他們在做什么,它們確實有安全用途。 禁止這樣做是非常嚴厲的。

(如果const rvalue引用重載是私有的,未定義的,或者導致編譯時或鏈接時錯誤,則可能更安全。對於#4情況尤其如此,我們返回引用但沒有任何內容很好地返回引用,語言不允許引用null。)

暫無
暫無

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

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