【问题标题】:Is it possible to get the original size of the class/struct before compiler align it?是否有可能在编译器对齐之前获得类/结构的原始大小?
【发布时间】:2017-02-10 16:33:39
【问题描述】:

我正在寻找一种在编译器对齐之前获取结构/类的原始大小的方法(更清楚地说是结构/类的成员字段的总和),如下所示:

struct Foo{
   char c;
   // the compiler will appen 3 bytes here
   int i;
};

sizeof(Foo) 返回 8 但原始大小为 5。

假设我们要编写一个模板函数或名为 orig_sizeof() 的宏

template <class t>
size_t orig_sizeof(t)
{
   // calculate the sum of the fields of t
}

当然sizeof是一个内部宏,一个没有源代码的关键字宏。

一种可能的方法是使用 __attribute__#pragma 更改结构对齐,而不是使用 sizeof 获取大小,然后将对齐恢复为默认值(也许 c++11 的 decltype 可能有用!),任何关于有用实现的想法?

编辑: 我试图通过比较 sizeof(type) 和 orig_sizeof(type) 来编写一个不接受作为参数的优化库,如果可能的话,要求用户重新对齐字段以获得更好的性能

【问题讨论】:

  • 不,不可能。
  • 1) 不要发送垃圾标签。 C 不是 C++ 不是 C。 2) 为什么你认为对象的大小会随着对齐而变化? 3) 如果sizeof(Foo) == 8,则Foo的大小 8
  • 没有“原始尺寸”之类的东西。你只是对 C++ 类型系统有一个错误的形象。
  • 确实如此,编译器会在结构中附加额外的字节,您可以自己尝试一下,比较sizeof ( struct { char c;char c1;int x; }; )sizeof ( struct {char c; int x;char c1; }; ) 它们分别是8和12
  • @DhiaHassen 编译器优化内存。你问的目的是什么?我很难理解。

标签: c++ struct alignment sizeof


【解决方案1】:

您可以在单独的标头中定义结构,并使用条件编译进行打包:

struct 
#ifdef pack
__attribute__((packed))
PackedFoo
#else
Foo
#endif
{
  char c;
  int i;
};

然后使用预处理器包含结构的打包和解包版本:

#include "foo.hpp"
#define pack
#include "foo.hpp"

这将允许您观察这两种尺寸,就好像它是同一类型一样:

//custom sizeof for packed representation
#define sizeof_packed(type) sizeof(Packed##type)

int main(){

  std::cout << sizeof(Foo) << '\n';        //prints 8
  std::cout << sizeof_packed(Foo) << '\n'; //prints 5
}

【讨论】:

    【解决方案2】:

    没有。 C++ 不提供该功能。将来,当众多反射提案中的一个进入标准时,您可能能够获得所有成员的大小。然而,它本质上是毫无意义的,不可能做你想做的事。原因如下:

    1) 在您的示例中,struct {char; int; }; 的长度始终为 8 个字节,无论成员的顺序如何。总会有 3 个字节的填充:要么在 charint 之间,最后,1 在 intchar 之间,最后是 2...不可能构建“有效打包”结构使用标准 C++。

    2) 继承。编译器可以为子成员重用父结构中的填充。其中的子集是空基优化,它可以使整个对象的大小小于其基数和成员的总和。或不。 EBO 不是强制性的。尝试确定 EBO 是否未被触发并且 struct 是否“有效打包”或者它已被触发并且您在某处有 2 个杂散字节的填充,玩得开心。

    3) 动态调度设施。通常它是你的类中的另一个不可见的指针成员(或者在多重继承的情况下是几个),它将自己的对齐要求添加到类中。然后(1)适用。更糟糕的是,您无法更改这些指针的放置位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 2012-05-05
      • 2020-07-30
      相关资源
      最近更新 更多