2013-02-08 20 views
4

何時基礎C++類型(如intfloat)具有未知初始值?基本C++類型何時具有未知初始值?

內存分配因子的類型如何呢?宣言呢?如果它是class/struct/union的成員呢? C++ 11與C++ 03或C++ 98不同嗎?

我有我的懷疑,但不知道如果我的知識是完全(或正確的,對於這個問題)

+0

那麼,這取決於初始化的類型。值初始化將它們歸零。然後你可以看到什麼時候使用了值初始化,比如'int i {};'。 – chris 2013-02-08 22:13:38

+0

未初始化的變量將具有未知的初始值,除非它是靜態或全局的(在這種情況下,它初始化爲所有位0)。 – jxh 2013-02-08 22:17:45

+0

*隱式*不是可應用於類型的術語(至少在標準中)。您可能想要以有限的方式使用*基本*類型或* POD *(普通舊數據),其中包括*基本*類型和一些僅由*基本*類型組成的用戶定義類型(它們共享大部分屬性*基本*類型)。我還提供了一個案例清單,回答您的上一個問題。 – 2013-02-08 22:23:43

回答

7

任何POD數據(包括所有的基本類型)將有一個未知的值當兩個:

  • 它沒有static memory allocation(它不是堆棧上創建或new
  • 它沒有初始化,包括空初始化和/或構造函數初始化列表

在調用main之前,將所有類型的全局/靜態變量設置爲零作爲啓動過程的一部分。在main1之前調用構造函數的構造函數。

未在構造函數中初始化的任何內容也是未知的。

編輯:澄清,std::string是「構造函數不初始化一切」一個很好的例子 - 如果你有一個本地std::string str;,然後str將有一個定義的「空字符串」的內容,但實際緩衝區的內容,或者實際上緩衝區指向的內容可能不會被設置爲任何有意義的內容 - 因爲實現可能會根據長度[或其他方式]確定一旦我們開始使用字符串來存儲內容時是否有可用的緩衝區]。

編輯2:正如評註所解釋的那樣,您也可以有「混合」情況,其中部分結構正在被初始化,例如,一個struct包含一些「普通數據」的元素和一些具有構造函數的元素。具有構造函數的構造函數將調用它的構造函數。普通數據不會被初始化。

1很可能是運行構造函數的代碼是main函數的一部分,或者是從main函數內部調用的,但是如果是這種情況,它會在「main中的任何代碼啓動之前」。

+1

+1因爲刺傷它......很難提供什麼和什麼時候將被初始化的準確定義。初始化的規則很複雜,並且有很多角落情況(例如,'struct S {int i; std :: string s;};'沒有用戶提供的構造函數,並且不是POD,它如果沒有爲實例提供初始化程序,只會被部分初始化 – 2013-02-08 22:32:48

+0

是的,所以'std :: string'屬於「任何未由構造函數初始化的東西」[字符串的一部分,比如length/size被初始化,但字符串緩衝區可能只是實現所喜歡的任何東西 - 未初始化,指向NULL,指向堆上未初始化的數據或其他東西]。 – 2013-02-08 22:38:27

+0

在上面的例子中,std :: string將被*初始化*構造函數(無論初始化實現者編碼的含義,在'std :: string'情況下可能是整個事物的意義),但是'i'將被初始化* – 2013-02-08 22:47:11

2

從 「運行的C++草案,2012年11月2日」

3.6.2非局部變量的初始化[basic.start.init]
2變量具有靜態存儲持續時間(3.7 .1)或線程存儲時間(3.7.2)應在任何其他初始化發生之前進行初始化(8.5) 。

帶有靜態存儲的變量是至少零初始化。

3.7。3自動存儲時間[basic.stc.auto]
2 [注意:這些變量按照6.7所述進行初始化和銷燬​​。 - 注完]

6.7隻字未提如何自動變量初始化。

3.7.4動態存儲持續時間[basic.stc.dynamic]
...
3.7.4.1分配函數[basic.stc.dynamic.allocation]
...有對從 分配函數返回的分配存儲的內容沒有限制。未指定通過對 分配函數的連續調用分配的存儲的次序,連續性和初始值

8.5初始化器[dcl.init]
7要默認初始化類型T的對象是指:
- 如果T是一個(可能是CV-合格)類型(第9節),默認構造因爲T被調用(並且如果T沒有可訪問的默認構造函數,則 初始化是不合格的);
- 如果T是一個數組類型,則每個元素都默認初始化;
- 否則,不執行初始化。

如果您提供了顯式的初始值設定項,則任何變量都將具有已知值。

如果您沒有爲POD類型提供顯式初始化程序,則它取決於存儲類。靜態或線程變量將被初始化爲零,而自動或動態分配的變量則不會。

如果您有複合類型,則適用相同的規則。如果您沒有明確的初始化程序,則通過(默認)構造函數或其他方式,基本類型的初始值取決於存儲類。

最後,通過malloc分配的內存將被初始化,而calloc內存將被初始化爲零。

+0

除非我爲類提供了一個無參數構造函數,否則它將使用該構造函數進行初始化。所以這是不完整的,會導致誤導。我知道有時候自動生成的默認構造函數也會初始化一些東西,但我不知道在哪種情況下會發生。 – Omnifarious 2013-02-08 22:44:21

+1

@Omnifarious這包含在'8.5 Initiailizers'中。問題是關於POD類型,而不是類類型。 – 2013-02-08 22:47:38