如果基类是骨料,是否可以保证不能被派生类重复使用的尾巴填充?

发布于 2025-02-06 13:17:46 字数 2645 浏览 2 评论 0原文

很多 61548135/c-gcc-tail-padding-reuse-and-pods“>许多 问题来自惊讶的C ++程序员,他们注意到只有在基类不是POD类型时才能重复使用尾垫。

例如,以下代码在x86-64 GCC上起作用( Godbolt链接):

struct A {
    int a;
    bool aa;
};
struct B : A {
    bool b;
};
struct C : B {
    bool c;
};
static_assert(sizeof(A) == 8);
static_assert(sizeof(B) == 12);
static_assert(sizeof(C) == 12);

这意味着字段c被放置在b的填充中,但是字段b未放在a的填充中。

链接的问题仅解释了特定的ABI指定了这种布局,一个答案甚至可以说重复使用POD类型的尾巴填充“打破程序员会做出的常见假设”,因此“基本上任何理智的编译器都赢了” t对这种类型进行尾填充重复使用。但是,这种解释并不令人满意,因为它实际上并不能保证任何东西。

标准是否可以保证POD类型的尾填充不会被派生的类重复使用吗?

There are many many questions from surprised C++ programmers who notice that tail padding is reused only when the base class is not a POD type.

For example, the following code works on x86-64 gcc (godbolt link):

struct A {
    int a;
    bool aa;
};
struct B : A {
    bool b;
};
struct C : B {
    bool c;
};
static_assert(sizeof(A) == 8);
static_assert(sizeof(B) == 12);
static_assert(sizeof(C) == 12);

This means that the field c is placed into the padding of B, but the field b is not placed into the padding of A.

The linked questions only explain that a particular ABI specifies this layout, and one answer goes as far as to say that reusing the tail padding of a POD type "breaks common assumptions a programmer would make", and so "basically any sane compiler won't do tail padding reuse" for such types. However, this explanation is unsatisfactory because it doesn't actually guarantee anything.

Does the standard guarantee that the tail padding of a POD type will not be reused by a derived class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

攀登最高峰 2025-02-13 13:17:46

完全重要的是一件事:汇总初始化。它与类型成员的布局无关。

这是由布局规则支配的。 a标准布局这是具有某些布局保证的类型的子集。类BC不是标准布局(或Pod,或您想称呼的任何内容),因此还有更多的差异在这些类型的布局中允许。

该标准允许任何实施方式通过其他答案指定。它们都同样有效。

可以使用非空基类中的填充物作为自己的子对象。这部分是因为做 memcpy in Base Class Subobjects(或任何任何其他可能重叠的子对象明确被禁止

对于琐碎的可复制类型的任何对象(除了潜在重叠的子对象)t ...

Being an aggregate matters for exactly one thing: aggregate initialization. It has nothing to do with the layout of the members of a type.

That is governed by the layout rules. A is standard layout, which is a subset of types that have certain layout guarantees. Classes B and C are not standard layout (or POD, or whatever you'd like to call it), so there is much more variance permitted in the layout of those types.

The standard permits any of the implementations specifies by the other answers. They're all equally valid.

It's OK for a type to use the padding in non-empty base classes for its own subobjects. This is in part because doing things like memcpy into base class subobjects (or any other potentially-overlapping subobject) is expressly forbidden:

For any object (other than a potentially-overlapping subobject) of trivially copyable type T ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文