当我查看以下程序及其输出时,我发现获取FrameA对象的返回值相当令人困惑:
当定义了一个空的构造函数时,输出如下:
在检查汇编代码后,我发现当使用编译器生成的构造函数时:
- when a empty ctor is defined, the member array field is remain uninitialized
when let the compiler generate the ctor, the member array field is initialized to all 0
auto a = f(); // f() --> return A();
#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;
}
当定义了一个空的构造函数时,输出如下:
但是使用编译器生成的构造函数时,输出结果为:g++ v4.8.1
72 (毫秒)
73 (毫秒)
我也在VC12上进行了测试,结果类似。g++ v4.8.1
1401 (毫秒)
1403 (毫秒)
在检查汇编代码后,我发现当使用编译器生成的构造函数时:
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]
但是使用空构造函数不会调用memset
来将FrameA数组设置为零。
有什么解释吗?
顺便说一下,我搜索了C++ 11草案n3242,但第8.5章的zero-initialize
和default-initialize
似乎没有涵盖这种情况。我错过了什么吗?
FrameA():data{} {}
。 - dyp