為什麼我這樣使用C 中的initializer list,在g 可以得到輸出而在msvc中不可以?

時間 2021-06-08 07:23:11

1樓:機犬

std::initializer_list 這東西雖然是在庫里提供的,但實現完全看編譯器怎麼開洞,大部分情況下值都在棧上,G++ 可能會直接指向靜態儲存區,我就遇到過 VC 爆棧 G++ 沒事的情況,就當成有型別的 va_list 用好了,常量或是比較大的容器初始化資料還是選 std::array 吧。

2樓:暮無井見鈴

按標準來說這是未定義行為,輸出時試圖訪問已經不存在的物件。

initializer_list 所引用的底層陣列的生存期類似臨時物件。用 new 表示式建立 initializer_list 時,底層陣列的生存期不會隨著 initializer_list 延長,而是只到完整表示式結尾。所以那 3 個 std::

string 在輸出之前就已經被析構了。

這裡輸出結果的區別大概是 MSVC 實現多做了一些收尾工作吧……參閱:[dcl.init.list]

[class.temporary]

std::initializer_list - cppreference.com

Reference initialization

3樓:

這個問題看起來像是vc沒把init-list表裡的元素內容一起建立到堆裡。

大括號對於init-list來說,基本是先解釋為乙個匿名陣列,然後取它的一頭一尾指標用於初始化乙個init-list物件。技術上init-list就是由兩個指標組成的,所以在new乙個這樣的物件的時候,編譯器計算出物件大小總是兩個指標那麼大,分配相應堆空間,然後呼叫建構函式初始化它們。重點在於,如果那個匿名陣列也同時被編譯器建立構造在堆上的話,new語句結束後沒有問題,init-list的指標還是指向穩定的內容。

反之如果編譯器認為應該在區域性棧上構建這個臨時陣列,那麼根據生命期原則,new語句結束後就立即析構這個陣列,但init-list內部的指標仍然指向那裡。所以試圖迭代列印出元素時候就等於列印析構後的string,故程式顯示為空。應該屬於未定義行為。

像vector就不會有問題,因為臨時陣列及其init-list只是構造的中間過程,內容最終還是要被複製到堆上的。

4樓:譚敘

嗯…… 看http://

cppreference.com

說initializer_list只有預設建構函式,所以GNU編譯器應該是按項賦值?

具體的頁面:

std::initializer_list - cppreference.com

c 中為什麼不提倡使用vector bool ?

陌歸 作為乙個 STL 容器,vector 確實只有兩個問題 1.它不是乙個STL容器 2.它並不容納 bool 因為vector 打包 bool 以節省空間,每個儲存在 vector 中的 bool 占用乙個單獨的bit,而禁止有指向單個位元的指標,所以vector不能編譯下式 vector v ...

Python中 init 的通俗解釋是什麼?

beatme 給例項賦值,初始化物件 就好像c裡面結構體的初始化,先malloc乙個結構體大小的記憶體 python裡是 new 然後給每個成員賦值。 小鮑 是否可以理解為函式引用,之前5 6年都在用Labview,跟這個開發環境很多的邏輯是互通的。匯入 init 方法後 其實也可以稱為函式 在整個...

c中struct 為什麼可以在資料結構這樣用?

是的,巢狀 指標型別是沒問題的。在C中,各種型別的指標本身只是乙個位址值,長度都是一樣的。但是只知道位址值你是沒法確定往後多少bit是你真正有效的資料範圍,所以指標就要加型別來確定往後取得範圍。所以你的struct裡面那個巢狀的東西只是乙個位址不是struct結構本身。到這裡你的編譯器是可以確認你整...