2011-08-24 81 views

回答

15

我認爲/Wp64已被棄用,主要是因爲編制了64位的目標將趕上種它的目的是捕獲錯誤的(/ Wp64僅在32位編譯有效)。當64位目標出現時,該選項被添加回來,以幫助人們將他們的程序遷移到64位,並幫助檢測不是「64位乾淨」的代碼。

這裏的各種問題與/Wp64的例子,微軟僅僅是不感興趣的固定 - 也許這是正確的(從http://connect.microsoft.com/VisualStudio/feedback/details/502281/std-vector-incompatible-with-wp64-compiler-option):

其實,STL是不是故意/Wp64不兼容,它完全並且無條件地與/Wp64不兼容,也不是 。 的根本問題是/Wp64與 模板的交互非常差,因爲__w64沒有完全集成到類型系統中。 因此,如果vector<unsigned int>vector<__w64 unsigned int>之前實例化,則它們兩者的行爲將類似於vector<unsigned int>,反之亦然。在x86上,SOCKET__w64 unsigned int的typedef。這並不明顯,但vector<unsigned int>在您的vector<SOCKET>之前正在實例化 ,因爲vector<bool>支持(在我們的 實施中)vector<unsigned int>

以前(在VC9和更早版本中),/Wp64 和模板之間的這種不良交互會導致虛假警告。然而,在VC10中,STL的更改爲 使情況變得更糟。現在,當vector::push_back()被給出 矢量本身的一個元素時,它在做其他工作之前計算出元素的索引 。該索引是通過從矢量的開始處減去 元素的地址而獲得的。在你的報告中, 這涉及到減去const SOCKET * - unsigned int *。 (後者 是unsigned int *而不是SOCKET *由於先前描述的 錯誤。)這種/要/觸發僞警告,說:「我 減去指針指向在x86同一類型,但 不同類型的64" 。但是,這裏有一個第二個錯誤,其中 /Wp64變得非常困惑,並且認爲這是一個硬性錯誤(而 爲unsigned int *添加了常量)。

我們同意這個錯誤信息令人困惑。但是,由於 之前有一個不可消除沉默的命令行棄用警告 D9035,所以我們認爲這應該足夠了。 D9035已經說 /Wp64不應該使用(雖然它不會繼續說「這 選項是超級麻煩車,現在完全沒有必要了」)。

在STL中,當使用/Wp64時,我們可以得到#error。但是, 會破壞仍在編譯/Wp64(儘管存在 棄用警告)的客戶,並且不會觸發此虛假錯誤。 STL 也可能發出警告,但編譯器已經發出D9035。

+0

Ahhh now * this *是一個令人信服的,合理的答案!非常感謝發佈它! :) +1 – Mehrdad

+0

事實上錯誤:「編譯爲64位目標將捕獲它旨在捕獲的錯誤種類(/ Wp64僅在32位編譯中有效)」...在VS2010/SP1上,您必須指定'/ Wp64'也可以在x64版本中使用,如果你想獲得'C4311'(*非常有用)。 user13251 laso在他的回答中提到了這一點。 –

0

您可以鏈接到棄用警告,但不能轉到/Wp64文檔?

默認情況下,Visual C++ 32位編譯器和Visual C++ 64位編譯器中的/ Wp64編譯器選項是關閉的。

如果您通過使用64位編譯器定期編譯應用程序,則可以在32位編譯中禁用/ Wp64,因爲64位編譯器將檢測到所有問題。

着重強調

+0

因此,他們只是因爲它不是100%的萬無一失而貶低它?我想,實際上它必須有一些*錯誤*,而不僅僅是它無法檢測到所有問題(它不像64位編譯器可以檢測到所有問題)...... – Mehrdad

+0

@Mehrdad - 它們是不贊成使用它,因爲64位編譯器在非可選的基礎上完成相同的工作。 –

+0

也許這只是我,但我覺得沒有說服力,對不起。 – Mehrdad

4

/Wp64在32位構建是浪費時間。它被棄用,這種棄用是有道理的。/Wp64在32位版本上的工作方式是在類型上尋找_w64註釋。這個_w64註釋會告訴編譯器,即使這種類型在32位模式下是32位,在64位模式下它也是64位。事實證明,這確實是一片混亂,尤其是涉及模板的地方。

/64位版本上的Wp64非常有用。文檔(http://msdn.microsoft.com/en-us/library/vstudio/yt4xw8fh.aspx)聲稱它在64位版本中默認處於打開狀態,但事實並非如此。編譯器警告C4311和C4312僅在明確設置/ Wp64時纔會發出。這兩個警告指示何時將32位值放入指針中,反之亦然。這些對於代碼的正確性非常重要,並聲稱處於警告級別1.我發現了非常普遍的代碼中的錯誤,如果開發人員已經爲64位版本打開了/ Wp64,則代碼​​將會停止。不幸的是,你也得到了你觀察到的命令行警告。我知道無法壓制這種警告,並且我學會了忍受這種警告。好的一面是,如果用警告作爲錯誤進行構建,則此命令行警告不會變成錯誤。

+0

您可以在不使用'/ Wp64'的情況下啓用這些警告,類似'/ w44311/w44312'。該文檔具有誤導性;這意味着這些警告是通過'/ Wp64'啓用的,而不是隻有在啓用「Wp64」時才能啓用。可悲的是,沒有「通常只有在啓用了」/ Wp64「時纔會啓用的警告列表,並且它們沒有出現在」默認情況下未啓用的警告「列表中,因此我們需要通過MSDN挑選才能找到他們:( –

+0

@BenHymers - 據我所知,**在VS2010 ** *只有*方式獲得'C4311'(甚至在x64構建)是指定'/ Wp64'。我認爲user13251的建議是現貨('/ w44311' does not * for *在我的VS2010上,也沒有相應的'編譯指示警告') –

+0

@MartinBa - 很好的信息,謝謝!我不記得我在2014年使用的編譯器,但我想象它在VS2012或VS2013中的描述...... :)希望2014年的我不僅僅是在製作東西! –

相關問題