Использование InterlockedIncrement - PullRequest
9 голосов
/ 05 марта 2009

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

15 голосов
/ 05 марта 2009

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

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

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

0 голосов
/ 13 марта 2009

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

0 голосов
/ 05 марта 2009

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

0 голосов
/ 05 марта 2009

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

...