考虑以下pod结构:
struct MessageWithArray {
uint32_t raw;
uint32_t myArray[10];
//MessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 } { };
};
运行以下内容:
#include <type_traits>
#include <iostream>
#include <fstream>
#include <string>
struct MessageWithArray {
uint32_t raw;
uint32_t myArray[10];
//MessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 } { };
};
//https://stackoverflow.com/questions/46108877/exact-definition-of-as-bytes-function
template <class T>
char* as_bytes(T& x) {
return &reinterpret_cast<char&>(x);
// or:
// return reinterpret_cast<char*>(std::addressof(x));
}
int main() {
MessageWithArray msg = { 0, {0,1,2,3,4,5,6,7,8,9} };
std::cout << "Size of MessageWithArray struct: " << sizeof(msg) << std::endl;
std::cout << "Is a POD? " << std::is_pod<MessageWithArray>() << std::endl;
std::ofstream buffer("message.txt");
buffer.write(as_bytes(msg), sizeof(msg));
return 0;
}
给出以下输出:
messagewitharray结构的大小:44
是吊舱吗?一
“message.txt”文件的十六进制转储如下:
00 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00
03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00
07 00 00 00 08 00 00 00 09 00 00 00
现在,如果我取消对构造函数的注释(这样
MessageWithArray
具有零参数构造函数),
带数组的消息
成为非pod结构。然后我使用构造函数来初始化。这会导致代码发生以下更改:
....
struct MessageWithArray {
.....
MessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 }{ };
};
....
int main(){
MessageWithArray msg;
....
}
运行此代码,我得到:
messagewitharray结构的大小:44
是吊舱吗?零
“message.txt”文件的十六进制转储如下:
00 00 00 00 0D 0A 00 00 00 14 00 00 00 1E 00 00
00 28 00 00 00 32 00 00 00 3C 00 00 00 46 00 00
00 50 00 00 00 5A 00 00 00 64 00 00 00
现在,我对实际的十六进制值不太感兴趣,我想知道的是
当sizeof()声明非pod结构转储与pod结构转储的字节数相同时,为什么非pod结构转储中还有一个字节
?是否可能由于构造函数使结构成为非pod,所以已向结构添加了隐藏的内容?sizeof()应该是一个精确的编译时检查,对吗?是否有可能避免使用sizeof()进行度量?
规格
我在Visual Studio 2017版本7.7.5,微软Visual C++ 2017上运行在Windows 10机器上的一个空项目中。
英特尔酷睿i7-4600M CPU
64位操作系统,基于x64的处理器
编辑
:我决定初始化结构以避免未定义的行为,因为问题在初始化时仍然有效。将它初始化为不带10的值将保留我最初观察到的行为,因为数组从未包含任何10秒的数据(即使它是垃圾和随机的)。