Как обеспечить выравнивание элемента по 4 байта? - PullRequest
3 голосов
/ 23 января 2010

Чтобы использовать OSAtomicDecrement (атомарная операция для Mac), мне нужно предоставить выровненный по 4 байта SInt32.

Работает ли этот вид приготовления? Есть ли другой способ решить проблемы с выравниванием?

struct SomeClass {
  SomeClass() {
    member_  = &storage_ + ((4 - (&storage_ % 4)) % 4);
    *member_ = 0;
  }

  SInt32 *member_;

  struct {
    SInt32 a;
    SInt32 b;
  } storage_;
};

Ответы [ 6 ]

5 голосов
/ 23 января 2010

Если вы на Mac, это означает GCC. GCC может автоматически выравнивать переменные для вас:

  __attribute__((__aligned__(4))) int32_t member_;

Обратите внимание, что это не переносимо между компиляторами, поскольку это специфично для GCC.

4 голосов
/ 23 января 2010

Я бы предположил, что любой SInt32 уже выровнен, даже на Mac.

Для уточнения:

struct Foo {
    SInt32 member;
};

элемент всегда выравнивается правильно, если только вы не упакуете структуру и не добавите member после символа.

1 голос
/ 23 января 2010

int с 4 байтами выровнены по умолчанию с любым из компиляторов OS X. Все, что вам нужно сделать, это не умышленно нарушать это выравнивание (например, путем неправильного приведения указателя, пометки вашей структуры как packed и т. Д.).

0 голосов
/ 24 января 2010

Если ваш компилятор поддерживает TR1 (или C ++ 0x), вы можете использовать шаблон std::aligned_storage.

Чтобы выделить пространство для объекта размером S и выравниванием A, вы можете выделить объект типа std::aligned_storage<S, A>::storage.

(Пространство имен может варьироваться в зависимости от компилятора. Я думаю, что TR1 не определяет, в какое пространство имен должны быть помещены расширения. В MSVC используется пространство имен std::tr1)

Кроме того, 32-разрядные целые числа уже 4-байтовые выровнены компилятором (по крайней мере, на платформах, где естественное выравнивание 32-разрядных чисел составляет 4 байта)

0 голосов
/ 23 января 2010

Если вы хотите принудительно настроить выравнивание в структуре, вы можете использовать битовые поля.

struct 
{
   Foo _hisFoo;
   unsigned int dummyAlignment : 0;
   Foo _myFoo;
}
0 голосов
/ 23 января 2010

Я ничего не знаю о программировании на Mac, но на миникомпьютерах, над которыми я работал, указатели всегда были выровнены по 4-байтовым (словесным) границам. IIRC, структуры были тоже. Выделенная память всегда была.

...