【问题标题】:Difference in struct sizes when #pragma pack(1) is used on Solaris and Linux在 Solaris 和 Linux 上使用 #pragma pack(1) 时结构大小的差异
【发布时间】:2014-01-28 14:57:55
【问题描述】:

当使用#pragma pack(1) 时,我发现Solaris 和Linux 之间的结构大小存在差异。在 Linux Derv 上大小为 128,但在 Solaris 上大小为 132。有人能告诉我为什么会这样吗?如何在 Solaris 上将其设置为 128?下面是代码:

#include <inttypes.h>
#include <iostream>
#include <stddef.h>

#pragma pack(1)
struct Base {
    char          m_1;
    uint8_t       m_2;
    uint64_t      m_3;
    uint64_t      m_4;
    uint16_t      m_5;
    uint32_t      m_6;
    uint32_t      m_7;
    uint64_t      m_8;
    uint64_t      m_9;
    uint32_t      m_10;
    char          m_11[6];
};

struct Derv : Base {
    int          m_1;
    char         m_2[66];
    int          m_3;
};
#pragma pack()

int main()
{
    std::cout << sizeof(Base) << ", " << sizeof(Derv) << std::endl;
    std::cout << offsetof(struct Derv, m_1)
              << ", " << offsetof(struct Derv, m_2)
              << ", " << offsetof(struct Derv, m_3)
              << std::endl;
}

编译如下: 在 Linux 上:g++ -Wno-invalid-offsetof struct_test.cpp 在 Solaris 上:CC -g0 -xarch=sse2 -mt struct_test.cpp

版本:

$g++ -v

使用内置规范。 目标:x86_64-redhat-linux 配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable -shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages= c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0- gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 线程模型:posix gcc 版本 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)

Solaris 编译器:

$CC -V

CC:Sun C++ 5.9 SunOS_i386 补丁 124864-13 2009/05/26

感谢您的宝贵时间。

【问题讨论】:

    标签: c++ c linux g++ solaris


    【解决方案1】:

    Sun C++ 编译器对该编译指示的理解略有不同。您还需要将选项 -misalign 传递给它,以便它允许比默认对齐更小。

    详情请参阅Sun Studio 12: C++ User's Guide

    【讨论】:

    • -misalign 仅在 SPARC 上受支持。
    【解决方案2】:

    Pragma pack 不保证不会有空格;充其量这意味着编译器将尽可能多地打包东西。我的建议是将结构中的项目从大到小重新排序;尽管从经验上无法保证(根据定义,编译指示依赖于实现),但通常可以消除结构包装中的“漏洞”。

    您可能还可以使用其他编译器标志,但如果您不关心结构中项目的顺序,则从最大到最小的顺序通常以更便携(-ish)的方式来解决问题。

    (显然,这并不总是一种选择——例如,如果你试图填充一个通过线路或传递给某些 API 的结构。但它适用于内部存储)

    【讨论】:

      【解决方案3】:

      Oracle Solaris Studio 12.3 C 编译器版本 5.12

      $ > man cc
      
      ... 
       -misalign
             (SPARC) Obsolete. You should not use this option. Use
             the -xmemalign=1i option instead. For a complete list
             of obsolete options and flags, see the C User's Guide.
      

      因此,在带有 C 编译器的 Oracle Solaris Studio 12.3 上,您应该使用

      -xmemalign=1i,不是-misalign

      另外,请参见 Oracle Solaris Studio 12.3:C 用户指南:2.11.19 #pragma pack http://docs.oracle.com/cd/E24457_01/html/E21990/bjaby.html#indexterm-96

      【讨论】:

        猜你喜欢
        • 2011-01-19
        • 2014-04-23
        • 1970-01-01
        • 2015-06-20
        • 1970-01-01
        • 1970-01-01
        • 2011-07-31
        • 2020-02-18
        • 2015-11-19
        相关资源
        最近更新 更多