solaris sparc和solaris x86之间的结构大小差异

solaris sparc和solaris x86之间的结构大小差异,c,solaris,sizeof,C,Solaris,Sizeof,我正在将我们的应用程序从solaris sparc移植到solaris x86,我遇到了这两种体系结构之间结构的大小差异。例如 我有一个类似的结构 typedef struct mystructS { double a; double b; double c; double d; double e; double f; double g; double h; double aa; double ab; double ac; double ad;

我正在将我们的应用程序从solaris sparc移植到solaris x86,我遇到了这两种体系结构之间结构的大小差异。例如 我有一个类似的结构

typedef struct mystructS
{
  double a;
  double b;
  double c;
  double d;
  double e;
  double f;
  double g;
  double h;
  double aa;
  double ab;
  double ac;
  double ad;
  double ae;
  double af
  double ag;
  double ah;
  int ba;
  int bb;
  int bc;
  char ca[256];
} mystructT;
在solaris X86中编写
sizeof(mystructT)
时,它返回396

在solaris SPARC中编写
sizeof(mystructT)
时,它返回400

我只是好奇,为什么会发生这样的事


编辑:两个solaris系统都是32位的。

如果SPARC是64位的,编译器可能会尝试在边界上对齐ca,这意味着它会在bc和ca之间额外填充4个字节。如果是这种情况,您可能会要求编译器打包结构,这样它就不会添加填充字节,但如何告诉它这样做往往取决于位编译器。

出于任何原因(可能需要在sparc上对齐Double,而不是在x86上对齐Double?),它似乎在尝试确保下一个结构在64位边界上对齐


也就是说,为了在内存中跳过sizeof(mystructT)步骤,并且仍然指向结构的开头(例如,当创建一个结构数组时,这就是在其上迭代时要做的事情),必须在最后填充结构。

由于结构成员填充和对齐始终是由实现定义的,因此您不应该对结构的大小做出任何假设(即使是在同一平台上同一编译器的不同版本之间,或具有不同优化设置的同一编译器之间)

如果需要特定的对齐和打包,则必须使用特定于编译器的指令来实现这一点。这可以通过命令行编译选项、
#pragma
指令或GCC和一些其他编译器的
\uuuuu属性
规范实现。或者更可靠地(但更多的工作)使用数据序列化。

最有可能的是,
alignof(double)
一个编译器为8,另一个编译器为4

结构的对齐方式被编译为其字段对齐方式的最小公倍数,在这种特殊情况下,这意味着
double
的对齐方式决定了
struct mystructS
的对齐方式


结构的大小必须是其对齐方式的倍数(如果您创建了这样一个结构的数组,这是为了让事情正常工作)。因此,结构的对齐方式为8的编译器也必须通过在末尾添加填充将大小舍入为8的倍数。

这没有什么意义,字符永远不需要对齐。为什么ca[0]会对齐,而ca[1]永远不会对齐?我可以确认Sun CC将x86上的双字节对齐到4字节边界,而将Sparc上的双字节对齐到8字节边界。FWIW,linux 86上的gcc将双倍对齐到8字节边界。+1在开始我自己的stddef之前,我应该更仔细地阅读现有的答案。'offsetof(3)'在这里也可以证明是有用的。我不认为该标准不能保证任何东西。不过,我从未见过在实现定义行为的上下文中讨论优化选项,如果您有参考资料,我将不胜感激。实际上,如果情况像你说的那样糟糕,我们就不会有ABI。“我的标准库”的系统标题中有结构定义,它们为system C编译器的所有优化级别定义了相同的布局。@Pascal:你可能是对的,没有那么糟糕;但是不同的系统有不同的ABI,但是编写代码时就好像这样并没有什么坏处。即使在x86上,Linux和Windows ABI也各不相同,在32位和64位版本之间也存在差异。