2009-03-05 2 views
9

При чтении о функции 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); 
} 

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

ответ

15

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

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

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

0

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

0

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

0

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

Смежные вопросы