假设我有两个类,我希望它们具有完全相同的内存布局:
struct A {
int x;
int y;
};
/* possibly more code */
struct B {
int a;
int b;
};
标准中有什么保证我可以安全static_assert(sizeof(A) == sizeof(B))
?
作为一个较弱的变体考虑
struct C {
int a;
};
static_assert( sizeof(A) >= sizeof(C) ); // can this ever fail?
static_assert( sizeof(A) > sizeof(C) ); // can this ever fail?
这个问题是由this one引发的。天真的我不希望任何断言失败,但这有保证吗?
标准中的任何内容都不会禁止实现,该实现确定了所有曾用作联合的一部分的结构,并在未以这种方式使用的任何结构的每个元素之后添加了随机数量的填充。另一方面,如果实现可以处理的标记数量,也没有任何东西会禁止实现以任意方式执行,也不会禁止实现强制限制为1。
所有这些都属于标准允许符合要求的实现所做的事情,但是即使标准允许,通常也应该避免做哪些质量实现。标准没有努力禁止实现做愚蠢的事情,也没有猜测某些专门的实现是否有充分的理由以非典型的方式处理某些东西。相反,它期望编译器编写者将尝试满足其客户的需求,无论标准是否要求他们这样做。
一个人为的反例:
#include <stdint.h>
struct A {
int32_t a;
int64_t b;
};
#pragma pack(4)
struct B {
int32_t a;
int64_t b;
};
static_assert(sizeof(A) == sizeof(B));
在64位Linux中使用g++
进行编译产生:
a.cc:15:1: error: static assertion failed
static_assert(sizeof(A) == sizeof(B));
断言可能为假的唯一实例是包装标准不同时。否则断言必须为真。
编译器只有结构定义来计算成员偏移量,所以除非layoùt是一致的,否则你将无法访问结构。