Использование InterlockedIncrement

Читая о функции 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);
}

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

4 ответа

Решение

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

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

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

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

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

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

Другие вопросы по тегам