15

为什么不推荐使用/Wp64Visual C++ 中的标志?

cl:命令行警告 D9035:
选项“Wp64”已被弃用,将在未来版本中删除

4

4 回答 4

17

我认为这/Wp64已被弃用,主要是因为为 64 位目标编译会捕获它旨在捕获的各种错误(/Wp64 仅在 32 位编译中有效)。当 64 位目标出现时,该选项被重新添加,以帮助人们将他们的程序迁移到 64 位并帮助检测不是“64 位干净”的代码。

/Wp64这是微软对修复不感兴趣的各种问题的示例- 可能是正确的(来自http://connect.microsoft.com/VisualStudio/feedback/details/502281/std-vector-incompatible-with- wp64-编译器选项):

实际上,STL 并不是故意不兼容/Wp64,也不是完全无条件不兼容/Wp64。潜在的问题是/Wp64与模板的交互非常糟糕,因为__w64没有完全集成到类型系统中。因此,如果vector<unsigned int>在 之前实例化vector<__w64 unsigned int>,那么它们的行为都会像vector<unsigned int>,反之亦然。在 x86 上,SOCKET__w64 unsigned int. 这并不明显,但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 上相同类型的指针,但指向 x64 上不同类型的指针”。但是,这里有一个第二个错误,其中 /Wp64真的很困惑,并认为这是一个硬错误(同时为 增加了 constness unsigned int *)。

我们同意这个虚假的错误信息令人困惑。但是,由于它前面有一个不可消除的命令行弃用警告 D9035,我们认为这应该足够了。D9035 已经说过/Wp64不应该使用它(尽管它没有继续说“这个选项是超级骗子,现在完全没有必要”)。

在 STL 中,我们可以#error何时/Wp64使用。但是,这会破坏仍在编译的客户/Wp64(尽管有弃用警告)并且不会触发此虚假错误。STL 也可能发出警告,但编译器已经发出 D9035。

于 2011-08-24T06:43:05.957 回答
4

/Wp64 在 32 位版本上是浪费时间。它已被弃用,这种弃用是有道理的。/Wp64 在 32 位构建上的工作方式是它会在类型上查找 _w64 注释。这个 _w64 注释会告诉编译器,即使这种类型在 32 位模式下是 32 位的,但在 64 位模式下它是 64 位的。事实证明这真的很不稳定,尤其是在涉及模板的情况下。

/Wp64 在 64 位版本上非常有用。文档(http://msdn.microsoft.com/en-us/library/vstudio/yt4xw8fh.aspx) 声称它在 64 位版本中默认开启,但事实并非如此。仅当显式设置 /Wp64 时才会发出编译器警告 C4311 和 C4312。这两个警告指示何时将 32 位值放入指针中,反之亦然。这些对于代码的正确性非常重要,并且声称处于警告级别 1。我在非常普遍的代码中发现了错误,如果开发人员为 64 位构建打开 /Wp64,这些错误将被阻止。不幸的是,您还会收到您观察到的命令行警告。我知道没有办法压制这个警告,我已经学会接受它。从好的方面来说,如果您将警告作为错误进行构建,则此命令行警告不会变成错误。

于 2013-02-11T18:55:56.280 回答
2

因为当使用 VS2010 中的 64 位编译器时,编译器会自动检测 64 位问题......这个开关是从过去你可以尝试检测运行 32 位编译器的 64 位问题开始的......

请参阅http://msdn.microsoft.com/en-us/library/yt4xw8fh%28v=VS.100%29.aspx

于 2011-08-24T06:33:45.250 回答
0

您可以链接到弃用警告,但无法转到/Wp64文档?

默认情况下,/Wp64 编译器选项在 Visual C++ 32 位编译器中处于关闭状态,在 Visual C++ 64 位编译器中处于打开状态。

如果您经常使用 64 位编译器编译您的应用程序,您可以在 32 位编译中禁用 /Wp64,因为 64 位编译器会检测所有问题。

强调添加

于 2011-08-24T06:34:24.767 回答