Разница в размерах структур при использовании #pragma pack (1) в Solaris и Linux

0

Я нахожу разницу в размере структуры между Solaris и Linux, когда используется #pragma pack (1). В Linux Derv имеет размер 128, но на Solaris размер 132. Может ли кто-нибудь сказать мне, почему это так? Как я могу получить его до 128 на Solaris? Ниже приведен код:

#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 - с-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

Спасибо за ваше время.

Теги:
g++
solaris

3 ответа

1
Лучший ответ

Пакет Pragma не гарантирует, что не будет пробелов; в лучшем случае это означает, что компилятор будет упаковывать вещи как можно больше. Мое предложение состоит в том, чтобы переупорядочить элементы в вашей структуре от самых больших до самых маленьких; хотя нет гарантии (прагмы, по определению, зависимые от реализации), эмпирически, что обычно будет избавляться от "дыр" в вашей структуре упаковки.

Могут быть другие флаги компилятора, которые вы можете использовать, но если вы не заботитесь о порядке элементов в своей структуре, заказ от самого большого до наименьшего обычно делает трюк в более портативном (-ish) способе.

(очевидно, это не всегда вариант - например, если вы пытаетесь заполнить структуру, которая проходит через провод или передается некоторому API, но она работает для внутреннего хранилища)

2

Компилятор Sun C++ понимает, что прагма немного отличается. Вам также необходимо передать ему опцию -misalign чтобы она позволяла меньше, чем выравнивание по умолчанию.

Более подробную информацию см. В Руководстве пользователя Sun Studio 12: C++.

  • 0
    -misalign поддерживается только на SPARC.
0

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 Guide.

Итак, в Oracle Solaris Studio 12.3 с компилятором C вы должны использовать

-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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню