std::initializer_list 的生命週期回傳值:GCC 與Clang 行為
在提供的程式碼中,您將傳回一個std : :initializer_list 來自函式並觀察意外的析構函式行為。具體來說,從函數傳回的陣列在您可以存取其元素之前就被銷毀了。
根本問題源自於這樣一個事實:根據 C 標準,std::initializer_list 具有一個元素數組,該數組是構造的生命週期與initializer_list相同。這意味著,預設情況下,陣列會在函數中的 return 語句結束時被銷毀。
GCC 的實作遵循此行為,而 Clang 則不然。 Clang 在傳回語句結束後維持陣列的生命週期,這不符合標準。然而,Clang 的行為顯得不一致,因為物件析構函數從未被呼叫。
複製列表初始化和編譯器解釋
帶有花括號的init- 的return 語句list 透過copy-list-initialization 初始化回傳值,這表示它複製初始化現有物件。在這種情況下,臨時的initializer_list物件是從大括號括起來的清單中複製初始化的。隨後,另一個initializer_list物件從第一個物件開始複製初始化。
標準規定數組的生命週期與initializer_list物件相同,但由於創建了initializer_list的多個副本,因此不清楚哪個物件的生命週期決定數組的生命週期。
GCC 考慮傳回的initializer_list 物件的生命週期來解釋標準,導致陣列過早銷毀。然而,8.5.4/6 中提供的範例表明數組的生命週期應延伸到封閉表達式的末尾,包括接收函數。
編譯器行為和標準歧義總結
建議
為了避免意外行為,通常不建議這樣做以值回傳 std::initializer_list。如果您需要傳遞可變數量的對象,請考慮使用容器類,例如 std::vector。
以上是為什麼 GCC 和 Clang 之間 `std::initializer_list` 傳回值的生命週期不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!