C++ 对于最后可能有空类成员的类,如何获得正确的sizeof?

C++ 对于最后可能有空类成员的类,如何获得正确的sizeof?,c++,C++,我知道空结构的大小是1,但当与模板结合使用时,这可能会导致类的大小可能会产生误导 例如,在下面的代码中,假设我正在编码一个二进制协议,其中有一些重要字段,后跟一个可选的结构 创建消息后,我们使用sizeof(message)执行memcpy,但我们总共得到2个字节,并尝试发送2个字节,尽管消息中只有1个字节。这是危险的,并导致一些解决消毒液问题 我已经研究过空基优化,但只有在可选字段处于开始时,它才会起作用。即使我们在这个特定的实例中不使用sizeof,sizeof也通常在其他通用代码中用于处理

我知道空结构的大小是1,但当与模板结合使用时,这可能会导致类的大小可能会产生误导

例如,在下面的代码中,假设我正在编码一个二进制协议,其中有一些重要字段,后跟一个可选的结构

创建消息后,我们使用sizeof(message)执行memcpy,但我们总共得到2个字节,并尝试发送2个字节,尽管消息中只有1个字节。这是危险的,并导致一些解决消毒液问题

我已经研究过空基优化,但只有在可选字段处于开始时,它才会起作用。即使我们在这个特定的实例中不使用sizeof,sizeof也通常在其他通用代码中用于处理类似的消息

struct EmptyClass{
    // empty class is 1 byte
};

struct NonEmptyClass{
    uint32_t j = 1; // non-empty class is 4 bytes
};



#pragma pack(push, 1) // exact fit - no padding
template <typename A>
struct Message{
    bool i = true; // example of an important field of 1 byte
    A a; // 1 byte if empty, 4 bytes if full
};
#pragma pack(pop)



int main() {
    Message<NonEmptyClass> a;
    std::cout << "Size of nonEmpty a: " << sizeof(a) << std::endl; // 5


    Message<EmptyClass> b;
    std::cout << "Size of Empty b: " << sizeof(b) << std::endl; // 2

    // memcpy b results in address-sanitizer issues, and likely garbage values for the second byte  

    return 0;
}
struct EmptyClass{
//空类是1字节
};
结构非空类{
uint32_t j=1;//非空类为4字节
};
#pragma-pack(推压,1)//精确贴合-无填充
样板
结构消息{
bool i=true;//1字节的重要字段示例
A;//如果为空,则为1字节;如果为满,则为4字节
};
#布拉格语包(流行语)
int main(){
信息a;
标准::cout
sizeof(Type)用于memcpying所述型号是否安全

对于所有普通的可复制类型,是的。更具体地说,复制填充字节是安全的

但在不同的系统中,类的表示并不一定相同,类不是表示二进制通信协议结构的理想方式


请注意,如果将示例扩展为实际使用
a
b
a.a
a.b
未初始化,则读取其值的行为未定义。
memcpy
本身实际上是安全的,但将复制的数据解释为
EmptyClass
NonEmptyClass
不是。

也许不同的设计会比模板更好?也许是包含所有必需前导字段的基本消息,然后使用继承添加越来越多的字段?要处理消息,您使用虚拟函数或访问者模式?不管类的大小如何。您始终可以y
sizeof(T)
类型为
T
的对象的字节进出(前提是
T
是POD)。这总是定义良好的。给出实际的代码和诊断,让您相信您有问题。