Я нахожу разницу в размере структуры между 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
Спасибо за ваше время.
Пакет Pragma не гарантирует, что не будет пробелов; в лучшем случае это означает, что компилятор будет упаковывать вещи как можно больше. Мое предложение состоит в том, чтобы переупорядочить элементы в вашей структуре от самых больших до самых маленьких; хотя нет гарантии (прагмы, по определению, зависимые от реализации), эмпирически, что обычно будет избавляться от "дыр" в вашей структуре упаковки.
Могут быть другие флаги компилятора, которые вы можете использовать, но если вы не заботитесь о порядке элементов в своей структуре, заказ от самого большого до наименьшего обычно делает трюк в более портативном (-ish) способе.
(очевидно, это не всегда вариант - например, если вы пытаетесь заполнить структуру, которая проходит через провод или передается некоторому API, но она работает для внутреннего хранилища)
Компилятор Sun C++ понимает, что прагма немного отличается. Вам также необходимо передать ему опцию -misalign
чтобы она позволяла меньше, чем выравнивание по умолчанию.
Более подробную информацию см. В Руководстве пользователя Sun Studio 12: C++.
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