簡體   English   中英

c++ 11: &v[0] 在空 std::vector v

[英]c++ 11: &v[0] on empty std::vector v

如果我有一個有時可能為空的 std::vector v ,那么 g++ 是否只是運氣好,我可以使用 &v[0] 獲得指向這個不存在數據的指針,或者我會得到其他編譯器的段錯誤(我的 g++ 在下面的情況下很好,並且在實際運行時從未給出過段錯誤)。

std::vector<int> v = {}; std::cout << (&v[0] == NULL) << std::endl; // true with my g++

謝謝

是的,您的代碼具有未定義的行為。

v[0]調用返回int&的 function ,並且沒有“空引用”,因此&v[0]首先永遠不能是 NULL 。 這就是為什么帶有優化的 clang 使您的代碼打印0並優化以下內容以return false;

bool is_pointer_to_first_null(std::vector<int>& v) {
    return &v[0] == nullptr;
}

(clang 也會警告你)

它還打破了std::vector<T>::operator[](n)的合同,它被定義為等同於*(v.begin() + n) ,並且因為v.begin() + 0 == v.begin() == v.end()對於空向量,這不是可取消引用的迭代器,並且您的標准庫實現可以做任何事情。
例如,如果定義了_GLIBCXX_DEBUG ,則會打印Error: attempt to subscript container with out-of-bounds index 0, but container only holds 0 elements. 與 g++。 https://godbolt.org/z/anran5

&v[0] == nullptr在 gcc 中沒有優化為false的事實是一個錯過的優化。 也許&v[0]已經首先優化為v.data()並且這是非空的信息丟失(或出於任何原因不使用)。
如果沒有優化,gcc 將很樂意形成空引用,因為引用是作為指針實現的,而&reference是匯編中的一個 noop。 對於大多數架構上的大多數編譯器來說都是如此,因此這不太可能出現段錯誤。


也許您正在尋找v.empty() (它仍然可以有一個非空數據指針)、 v.data() == nullptr (定義時, v.data() == &v[0] )或v.capacity() == 0 不過,不應該有充分的理由檢查數據指針是否為 null。

暫無
暫無

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

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