当前位置: 首页 > 知识库问答 >
问题:

结构根据空基类顺序更改大小

支彭亮
2023-03-14

我正在写一个数学向量和矩阵库来练习,我使用crtp基类来避免多次定义几个函数。我还继承了一个静态数组类。根据继承类的顺序,我在msvc中的结构会有不同的大小。这是一个错误,还是我应该预料到的?你可以在以下位置找到一个现场演示:https://godbolt.org/z/3EPVI5注意,同样的编译在gcc中也很好。参考代码:

template<typename D>
struct crtp
{

};

template<typename T, int s>
struct arr_impl
{
    T e[s];
};

template<typename T, int s>
struct vc : public arr_impl<T, s>, public crtp<vc<T, s>>
{

};

template<typename T, int s>
struct vc2 : public crtp<vc2<T, s>>, public arr_impl<T, s>
{

};

int main()
{
    static_assert(sizeof(vc<vc<float,3>,2>) == 24);
    static_assert(sizeof(vc2<vc2<float,3>,2>) == 24);
    return 0;
}

我已经进一步缩小了范围,请参见:https://godbolt.org/z/tGCn_J因为它似乎只需要嵌套和一个空类:

struct empty_struct{};

template<typename T>
struct st
{
    T a;
};

template<typename T>
struct vc : public empty_struct, public st<T> {};

template<typename T>
struct vc2 : public st<T>, public empty_struct{};

int main()
{
    static_assert(sizeof(vc<vc<float>>) == 4);
    static_assert(sizeof(vc2<vc2<float>>) == 4);
    return 0;
}

共有1个答案

荀正谊
2023-03-14

我相信MSVC在这方面符合C17标准。

源自[intro.object](强调我的):

除非是位域,否则大多数派生对象的大小应为非零,并应占用一个或多个存储字节。基类子对象的大小可以为零。简单复制或标准布局类型的对象应占用连续的存储字节。

这就是C17标准在这个问题上的全部内容。空基优化是完全可选的。该标准只是说它是合法的,而不是说它必须执行,或者在什么情况下应该执行。

目前的C20标准草案更具规范性。

来自[intro.object](再次强调我的观点)

如果一个对象
--不是潜在的重叠子对象,或者
--不是类类型,或者
--是具有虚拟成员函数或虚拟基类的类类型,或者
--具有非零大小的子对象或非零长度的位字段,则该对象具有非零大小。否则,如果该对象是标准布局类类型的基类对象,没有非静态数据成员,则该对象具有零大小。否则,该对象具有零大小的情况是实现定义的。除非是位域,否则具有非零大小的对象应占用一个或多个存储字节,包括其任何子对象全部或部分占用的每个字节。简单复制或标准布局类型([basic.types])的对象应占用连续的存储字节。

因此,在C 20下,基类的大小保证为零,因为它是标准布局类的空基类。

 类似资料:
  • 问题内容: 有什么方法可以增加文档开头的用语吗?例如,我有3个文档。 XXX应该在搜索词“ Sulpher”的顶部列出,因为那是该文档中的第一个单词。如果YYY列在顶部,则可以,因为与XXX相同。但是ZZZ应该永远是最后一个。换句话说,在“左侧”找到的术语应比在“右侧”找到的术语具有更高的优先级。 问题答案: 您可以通过小写标准化术语位置来提高: 然后 屈服

  • 问题内容: 我在一个响应式网站上工作,遇到一个有趣的问题。我并排有一些div。可能有2到6个左右的任何地方。当屏幕的宽度不足以正确显示所有内容时,div将垂直堆叠。使用CSS足够简单。 我可以使用并手动设置位置,但是这会使父级缩小并且不能正确包含它们。 更复杂的是,我不能使用JavaScript。 使用两列: (未试) HTML: CSS: HTML,有4列: 问题答案: 得益于出色的flexbo

  • 顺序结构 #include <stdio.h> #include <stdlib.h> int main01(void) { printf("%d \n", 1);//顺序结构,从上往下执行,从main函数开始 printf("%d \n", 11); printf("%d \n", 111); printf("%d \n", 1111); sys

  • 问题内容: 我在一个响应式网站上工作,遇到一个有趣的问题。我有一些并排的div。可能有2到6个左右的任何地方。当屏幕的宽度不足以正确显示所有内容时,div将垂直堆叠。使用CSS足够简单。 问题是,我需要根据布局以不同的顺序排列它们。使用2或3个div([根据width更改div的顺序])很容易做到这一点,但是当您添加第四个[div时,难度就更大。 我可以使用并手动设置位置,但是这会使父级缩小并且不

  • 我有一个可折叠的导航条构建与bootstrap 4。我使用了col-sm-2和navbar-expand-sm来使它以相同的屏幕尺寸折叠成一个汉堡包,它应该占据整个宽度。 问题是在sm屏幕尺寸以上,我希望它有h-100,所以它是一个侧栏,但作为sm/xs,我希望它只是占用拨动按钮所需的空间。 有没有办法用bootstrap来实现这一点,或者我被困在jquery中添加/删除h-100类?

  • 主要内容:顺序表的初始化顺序表,全名 顺序存储结构,是 线性表的一种。通过《 什么是线性表》一节的学习我们知道,线性表用于存储逻辑关系为“一对一”的数据,顺序表自然也不例外。 不仅如此,顺序表对数据的物理存储结构也有要求。 顺序表存储数据时,会提前申请一整块足够大小的物理空间,然后将数据依次存储起来,存储时做到数据元素之间不留一丝缝隙。 例如,使用顺序表存储集合  ,数据最终的存储状态如图 1 所示: 图 1 顺序存储结