Вопрос

Читая о функции InterlockedIncrement Я заметил, что переданная переменная должна быть выровнена по 32-битной границе. Обычно я видел код, который использует InterlockedIncrement так:

class A
{
 public:
   A();
   void f();

 private:
  volatile long m_count;
};

A::A() : m_count(0)
{
}

void A::f()
{
  ::InterlockedIncrement(&m_count);
}

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

Это было полезно?

Решение

Это зависит от настроек вашего компилятора. Однако по умолчанию все восемь байтов и младше будут выровнены по естественной границе. Таким образом, " int " мы выровнены по 32-битной границе.

Кроме того, " #pragma pack " Директива может быть использована для изменения выравнивания внутри модуля компиляции.

Я хотел бы добавить, что ответ предполагает Microsoft C / C ++ компилятор. Правила упаковки могут отличаться от компилятора к компилятору. Но в целом, я бы предположил , что большинство компиляторов C / C ++ для Windows используют одни и те же настройки по умолчанию, чтобы немного упростить работу с заголовками Microsoft SDK.

Другие советы

Код выглядит хорошо (переменные будут правильно выровнены, если вы специально не сделаете что-то, чтобы это сломать - обычно с использованием преобразования или «упакованных» структур).

Да, это будет работать нормально. Компиляторы обычно выравнивают, если не указано иное.

Строго говоря, это действительно зависит от того, как вы используете A, например, если вы упаковали " A " объект в оболочке ITEMIDLIST или структура с неправильным "набором прагмы" данные могут быть неправильно выровнены.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top