2013-06-27 20 views
3

編譯這個頭:保證不對性病正確對準:: string的

// myheader.h 

class MyClass { 

    MyClass(); 
    ~MyClass(); 

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

與Visual Studio 2010/W4(有人告訴我這樣做),目標64,給了我以下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。你的更新:嘗試將這個類定義複製到一個單獨的文件並孤立地編譯,而不包括任何不必要的東西。如果這仍然產生警告,那麼只是微軟很愚蠢。否則,它是來自其他代碼的東西(例如'#pragma pack(push)',沒有對應的'pop'。 – jalf

回答

2

獨立於編譯器的便攜式解決方案恰恰是您向我們展示的代碼。如果你不做任何事情來破壞它,編譯器會正確地對齊所有東西。 (如使用需要特殊對齊SIMD類型,或使用#pragma pack

如果您使用的是#pragma pack,則:

  1. 你爲什麼不告訴我們?
  2. 不要

如果您向我們展示的代碼在/ W4中給出了任何警告,請歸咎於Microsoft。該代碼是正確的,便攜式和安全的(不像代碼,它使用pack編譯指示)。

微軟對於/ W4的警告有一些奇怪的想法。大多數編譯器只針對看起來像可能包含錯誤的內容發出警告。

微軟有一大堆警告基本上是說「我沒有理由懷疑這個代碼存在問題,但是如果你寫了不同的代碼,它可能包含一個bug」,這純粹是無稽之談。

與其他編譯器一般建議編譯時啓用所有警告。在微軟的編譯器上,這並不是真正可行的。 (雖然你可以使用/ W4和選擇性沉默特定廢話警告)

認爲他們明確告訴你的是,該結構包含填充字節(所以,如果你使用#pragma pack,它會改變班級的佈局,而其中一名受影響的班級成員會對這種變化「敏感」)。

如果可能的話,可以考慮重新排列類成員,使他們在按大小順序排列。這給你更緊湊的課堂布局,只有在課堂結束時纔有填充(如果有的話)。

但是沒有什麼錯誤與您正在使用的類定義。

+0

有一些操作不會告訴我們。msvc does not just generate this warning for沒有理由 –

+0

@JohnDibling是的,我懷疑這個問題(請參閱我對這個問題的評論),但只給出了我們已經顯示的代碼,代碼沒有任何問題(並且我沒有Windows機器在手邊測試它,看看我是否可以挑起這個警告)但是,我同意它的表現,就好像他在別的地方做別的事情一樣,這導致課堂被打包 – jalf