加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 普通旧数据 – 对齐要求

发布时间:2020-12-16 06:51:55 所属栏目:百科 来源:网络整理
导读:假设我有两个具有相同初始序列成员的POD结构A和B,但稍后会有一些差异(我知道,这可以通过继承轻松解决). struct A { int x; uint64_t y; int z;};struct B { int x; uint64_t y; int8_t z;}; 指向struct的指针需要指向intitial成员(§9.2.20[class.mem]). 现
假设我有两个具有相同初始序列成员的POD结构A和B,但稍后会有一些差异(我知道,这可以通过继承轻松解决).

struct A {
    int x;
    uint64_t y;
    int z;
};
struct B {
    int x;
    uint64_t y;
    int8_t z;
};

指向struct的指针需要指向intitial成员(§9.2.20[class.mem]).

现在另外两个问题:

>在标准中我发现成员不能重新排序.我很确定这是这种情况,因为结构需要与C完全兼容,并且对于C,规定内存地址必须按声明的顺序增加.
>两个结构中的共同成员的对齐必须相同吗?即,以下总是如此:

A a;
B b;
assert(offsetof(A,y) == offsetof(B,y));

如果不是:至少如果我把结构放入一个联合,那么这应该成立,因为标准(§9.2.19[class.mem])说

If a standard-layout union contains two or more standard-layout structs that share a common initial sequence,and if the standard-layout union object currently contains one of these standard-layout structs,it is permitted to inspect the common initial part of any of them.

我在这里添加一个额外的例子.

struct A {
    int x;
    uint64_t y;
    int z;
};
struct B {
    int x;
    uint64_t y;
    int8_t z;
};
B convertToB(A& a);
void g() {
    A a;
    // at this point,I cannot rely on offset(A,y) == offset(B,y)
    B b = convertToB(a);
    // since I do the copy over the union,offset(A,y) holds
}
union U {
     A asA; 
     B asB;
};
B convertToB(A& a) {
    U u;
    // at this point,y) holds
    u.asA = a;
    return u.asB;
}

由于我没有机会知道在某个时刻是否会发生关于联合的副本,并且结构必须在任何地方都相同,我声称,偏移量(A,y)==偏移量(B,y)必须保持不变.

解决方法

您可以在此处找到对象成员的观察要求:

9.2/13: Nonstatic data members of a (non-union) class with the same access control are allocated so that later members have higher
addresses within a class object. The order of allocation of non-static
data members with different access control is unspecified.
Implementation alignment requirements might cause two adjacent members
not to be allocated immediately after each other; so might
requirements for space for managing virtual functions and virtual base
classes.

在您的结构中,所有成员都具有相同的访问类,因此您可以在此处获得有关订单的保证.

但请注意引用的最后一句:不能保证两个连续成员之间的空间是相同的(虽然不太可能).这就是为什么我建议采用工会方法.您不仅可以从标准保证中受益,而且还可以在源代码中清楚地传达您的意图.

编辑

我们可以考虑另一个方面:POD类型是一种普通类型,并且具有标准布局.

9.2/16: Two standard-layout struct types are layout-compatible if they have the same number of non-static data members and corresponding
non-static data members (in declaration order) have layout-compatible
types

3.9/11: If two types T1 and T2 are the same type,then T1 and T2 are layout-compatible types.

一旦你的结构在某个时刻发散,你就会发现你没有任何保证.但是我知道这可以保证u.asB与它返回的B对象的布局兼容.

最后,我希望通过简单的可复制对象找到更实际的保证:

3.9/2: For any object (other than a base-class subobject) of trivially copyable type T,whether or not the object holds a valid
value of type T,the underlying bytes making up the object can be
copied into an array of char or unsigned char. If the content of the
array of char or unsigned char is copied back into the object,the
object shall subsequently hold its original value.

我认为可以从中推断出,在你的情况下,在联合中存储一个值但是读取另一个值会起作用.但请注意,根据此(非规范性)说明,这不是一般事实:

9.5/4: [Note: In general,one must use explicit destructor calls and placement new operators to change the active member of a union. —end note]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读