2013-06-27 4 views
3

Компиляция заголовок:Убедите правильное выравнивание по станд :: строка

// myheader.h 

class MyClass { 

    MyClass(); 
    ~MyClass(); 

    unsigned int mMyUint; 
    bool bMyBool; 
    std::string sMyString; 
}; 

с Visual Studio 2010/W4 (мне сказали, чтобы сделать это), цель x64, дает мне следующее warning C4121:

'MyClass' : alignment of a member was sensitive to packing, ссылаясь на строку, где находится std::string sMyString. official help of Microsoft предлагает использовать #pragma pack(x), где x будет 1, 2, 4 в зависимости от элементов, которые используются внутри его структуры/класса.

Нет, мне интересно, какое выравнивание использовать для std :: string? Моя идея заключалась в том, что std :: string не является ни компилятором, ни независимым от платформы. Есть ли способ решить эту проблему, особенно с учетом других членов, которые могут иметь любой другой агит?

Лучшим было бы независимое от компилятора (и даже портативное) решение.

Обновление: Относительно очень полезного ответа, предоставленного jalf: Нет, в этом файле я не использую #pragma pack(x). Я использовал его в другой структуре, где я использую бит-поля, которые я видел, заполняются, когда не используют #pragma pack(x). Теперь я был просто встревожен, столкнувшись с той же ловушкой, потому что не знал, как компилятор Microsoft разрешает std::string.

+0

Он просто говорит вам, что в вашей структуре есть пространство. Вы не должны упаковывать его без причины. Перестановка членов может заставить это глупое предупреждение уйти, просто проигнорируйте его. – PlasmaHH

+0

Re. ваше обновление: попробуйте скопировать это определение класса в отдельный файл и скомпилировать его изолированно, не включив ничего лишнего. Если это все еще выдаст предупреждение, значит, Microsoft просто глупо. В противном случае это что-то из остальной части вашего кода (например, '#pragma pack (push)', без соответствующего 'pop'. – jalf

ответ

2

Некоммерческое и портативное решение для компилятора: точно код, который вы нам указали. Компилятор позаботится о правильном выравнивании, если вы не сделаете ничего, чтобы сорвать его. (Например, с использованием типов SIMD, которые требуют специального выравнивания, или с помощью #pragma pack)

Если вы используете #pragma pack, то:

  1. почему не показать нам?
  2. не.

Если код, который вы нам указали, дает вам предупреждения в/W4, обвините Microsoft. Код правильный, переносимый и безопасный (в отличие от код, который использует прагму pack).

У Microsoft есть некоторые странные идеи относительно предупреждений в/W4. Большинство компиляторов только выдает предупреждения для вещей, которые выглядят как они может содержать ошибки.

Корпорация Майкрософт имеет массу предостережений, в основном говоря: «У меня нет причин подозревать, что есть проблема с этим кодом, но если вы написали ее по-другому, это может содержать ошибку», которая является чистой бессмыслицей.

С другими компиляторами я обычно рекомендую компиляцию с включенными предупреждениями. В компиляторе Microsoft это не реально. (Хотя вы можете использовать/W4 и выборочно молчание конкретных предупреждений нонсенса)

Что я думаю они специально говорят вам, что структура содержит байты заполнения (и поэтому, если вы сделали использование #pragma pack, его изменит макет класса, и один из затронутых членов класса будет «чувствителен» к этому изменению).

Если возможно, подумайте о перегруппировке элементов, чтобы они были перечислены в порядке убывания размера. Это дает вам более компактные макеты классов с заполнением (если есть) только в конце класса.

Но ничего нет Неверный с определением класса, которое вы используете.

+0

есть что-то, о чем нам не говорит. Msvc не генерирует это предупреждение для нет причины. –

+0

@ JohnDibling Да, я подозреваю, что так много (см. мой комментарий к вопросу). Но, учитывая только код, который мы показали, в коде нет ничего плохого. (И у меня не было Windows-машины чтобы проверить, не могу ли я спровоцировать предупреждение). Но да, я согласен. Это похоже на то, что он что-то делает где-то еще, что заставляет класс упаковываться – jalf