Использование 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 или структуру с плохим "пакетом прагмы", данные могут быть неправильно выровнены.