簡體   English   中英

初始化數組,放置新的,讀取變量,定義的行為?

[英]initialize array, placement new, read variables, defined behavior?

給定一個只有成員的類是char[10] ,它沒有繼承,也沒有虛擬成員,它有一個構造函數,它沒有以任何方式提及數組(這樣它得到默認初始化 - >沒有初始化,如下所示:

class in_place_string {
    char data[10];

    static struct pre_initialized_type {} pre_initialized;
    in_place_string(pre_initialized_type) {}  //This is the constructor in question

    in_place_string() :data() {} //this is so you don't yell at me, not relevent
};

它是否定義了將此類放置到已有數據的緩沖區中的行為,然后從數組成員中讀取?

int main() {
    char buffer[sizeof(in_place_string)] = "HI!";
    in_place_string* str = new(buffer) in_place_string(in_place_string::pre_initialized);
    cout << str->data; //undefined behavior?
}

我很確定它沒有很好地定義,所以我問這是實現定義還是未定義的行為。

你沒有執行reinterpret_cast (這不安全,因為這個類有非平凡的初始化); 您正在創建一個其成員未初始化的新對象。

對未初始化的對象執行lvalue-> rvalue轉換會給出不確定的值和未定義的行為。 那個對象是未初始化的嗎?

根據5.3.4, new-expression創建的所有對象都具有動態存儲持續時間。 新的展示位置也不例外。

由new-expression創建的實體具有動態存儲持續時間

然后8.5說

如果沒有為對象指定初始化程序,則默認初始化該對象。 當獲得具有自動或動態存儲持續時間的對象的存儲時,該對象具有不確定的值,並且如果沒有對該對象執行初始化,則該對象保留不確定的值,直到該值被替換(5.17)。 [注意:具有靜態或線程存儲持續時間的對象是零初始化的,請參閱結束注釋]如果評估產生不確定的值,則行為是未定義的,除非在以下情況中:

並且以下情況僅允許unsigned char ,即使這樣,該值也沒有用。

在您的情況下,新對象具有動態存儲持續時間(!),並且其未執行初始化的成員具有不確定的值。 閱讀它們會給出未定義的行為。

我認為有關條款是8.5 [dcl.init]第12段:

如果沒有為對象指定初始化程序,則默認初始化該對象。 當獲得具有自動或動態存儲持續時間的對象的存儲時,該對象具有不確定的值,並且如果沒有對該對象執行初始化,則該對象保留不確定的值,直到該值被替換(5.17)。 [注意:具有靜態或線程存儲持續時間的對象是零初始化的,請參見3.6.2。 -end note]如果評估產生不確定的值,則行為是未定義的,除非在以下情況中:

  • 如果通過以下評估產生無符號窄字符類型(3.9.1)的不確定值:
    • 條件表達式的第二個或第三個操作數(5.16),
    • 逗號表達式的右操作數(5.18),
    • 轉換的操作數或轉換為無符號窄字符類型(4.7,5.2.3,5.2.9,5.4),或
    • 丟棄值表達式(第5條),然后操作的結果是不確定的值。
  • 如果通過評估一個簡單賦值運算符(5.17)的右操作數產生無符號窄字符類型的不確定值,該操作數的第一個操作數是無符號窄字符類型的左值,則不確定值將替換所引用的對象的值。左操作數。
  • 如果在初始化無符號窄字符類型的對象時通過初始化表達式的求值產生無符號窄字符類型的不確定值,則該對象被初始化為不確定的值。

我不認為任何例外情況適用。 由於在構造對象之后初始化之前讀取了值,因此我認為代碼會導致未定義的行為。

暫無
暫無

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

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