[英]Does default constructor zero-initialize member array variable?
當我用它的輸出檢查下面的程序時,我發現通過返回值獲取FrameA對象非常困惑:
當讓編譯器生成ctor時,成員數組字段被初始化為全0
auto a = f(); // f() --> return A();
鑒於以下SSCCE
#include <cstring>
#include <iostream>
#include <chrono>
#include <algorithm>
using namespace std;
const int MAX = 9999999;
struct FrameA {
// FrameA() {}
// FrameA(const FrameA &v) { memcpy(data, v.data, sizeof(data)); }
char data[1000];
};
FrameA f(int i) { return FrameA(); }
int test(int odd) {
int sum = 0;
auto begin = chrono::steady_clock::now();
for (int i = 0; i < MAX; ++i) {
auto v = f(odd);
sum += v.data[0] + v.data[330];
}
auto end = chrono::steady_clock::now();
cout << chrono::duration_cast<chrono::milliseconds>(end - begin).count()
<< " (milliseconds)" << endl;
return sum;
}
int _tmain(int argc, _TCHAR *argv[]) {
test(0);
test(1);
return 0;
}
定義空ctor時,輸出如下:
g ++ v4.8.1
72(毫秒)
73(毫秒)
但是使用編譯生成的ctor,輸出是:
g ++ v4.8.1
1401(毫秒)
1403(毫秒)
我也在VC12上測試過,結果很相似。
檢查程序集后,我發現在使用編譯器生成的ctor時:
for (int i = 0; i < MAX; ++i) {
auto v = f(odd);
00A31701 push 3E8h
00A31706 lea eax,[ebp-3F8h]
00A3170C push 0
00A3170E push eax
00A3170F call _memset (0A32460h) ;; memset FrameA to 0
sum += v.data[0] + v.data[330];
00A31714 movsx eax,byte ptr [ebp-3F8h]
但是使用空ctor不會調用memset
將FrameA中的數組設置為零。
這有什么解釋嗎?
順便說一句,我搜索了C ++ 11草案n3242,但是第8章zero-initialize
和default-initialize
似乎並沒有涵蓋這種情況。 我錯過了什么嗎?
FrameA()
將對對象進行值初始化(§5.2.3/ 2):
表達式
T()
,其中T
是非數組完整對象類型的簡單類型說明符或類型名稱說明 符 ,或者(可能是cv限定的)void
類型,創建指定類型的prvalue,它是值 -初始化
初始化沒有用戶提供的構造函數的非聯合類類型的值將對其進行零初始化(第8.5 / 7節):
如果
T
是一個(可能是cv限定的)非聯合類類型而沒有用戶提供的構造函數,那么該對象是零初始化的,如果T
的隱式聲明的默認構造函數是非平凡的,則調用該構造函數。
這將零初始化其每個成員。
初始化具有用戶提供的構造函數的類類型將簡單地調用構造函數(在您的情況下,不會初始化數組)(§8.5/ 7):
如果
T
是具有用戶提供的構造函數(12.1)的(可能是cv限定的)類類型(第9節),則調用T
的默認構造函數(如果T
沒有可訪問的默認構造函數,則初始化是錯誤的) ;
使用默認構造函數構造類型為T
的對象時,即使用T()
您將獲得值初始化或默認構造,具體取決於T
的定義方式:
T
沒有默認構造函數或者具有默認的默認構造函數,則編譯器負責初始化:編譯器值初始化所有成員。 對於內置類型值初始化意味着它是零初始化的 ,即,值接收它們對應的合適的零表示。 T
具有非默認的默認構造函數,則T
的程序員接管初始化成員的責任。 成員要么在成員初始化列表中列出並相應地初始化,要么默認初始化 。 內置類型的默認初始化意味着沒有任何反應,即這些成員未初始化。 A()
使用值初始化 。 正如您所注意到的,這取決於A
是否具有用戶聲明的默認構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.