15

Why is the /Wp64 flag in Visual C++ deprecated?

cl : Command line warning D9035 :
option 'Wp64' has been deprecated and will be removed in a future release

Bibhas Debnath
  • 14,559
  • 17
  • 68
  • 96
user541686
  • 205,094
  • 128
  • 528
  • 886

4 Answers4

17

I think that/Wp64 is deprecated mainly because compiling for a 64-bit target will catch the kinds of errors it was designed to catch (/Wp64 is only valid in 32-bit compiles). The option was added back when 64-bit targets were emerging to help people migrate their programs to 64-bit and help detect code that wasn't '64-bit clean'.

Here's an example of the kinds of problems with /Wp64 that Microsoft just isn't interested in fixing - probably rightly so (from http://connect.microsoft.com/VisualStudio/feedback/details/502281/std-vector-incompatible-with-wp64-compiler-option):

Actually, the STL isn't intentionally incompatible with /Wp64, nor is it completely and unconditionally incompatible with /Wp64. The underlying problem is that /Wp64 interacts extremely badly with templates, because __w64 isn't fully integrated into the type system. Therefore, if vector<unsigned int> is instantiated before vector<__w64 unsigned int>, then both of them will behave like vector<unsigned int>, and vice versa. On x86, SOCKET is a typedef for __w64 unsigned int. It's not obvious, but vector<unsigned int> is being instantiated before your vector<SOCKET>, since vector<bool> is backed (in our implementation) by vector<unsigned int>.

Previously (in VC9 and earlier), this bad interaction between /Wp64 and templates caused spurious warnings. In VC10, however, changes to the STL have made this worse. Now, when vector::push_back() is given an element of the vector itself, it figures out the element's index before doing other work. That index is obtained by subtracting the element's address from the beginning of the vector. In your repro, this involves subtracting const SOCKET * - unsigned int *. (The latter is unsigned int * and not SOCKET * due to the previously described bug.) This /should/ trigger a spurious warning, saying "I'm subtracting pointers that point to the same type on x86, but to different types on x64". However, there is a SECOND bug here, where /Wp64 gets really confused and thinks this is a hard error (while adding constness to the unsigned int *).

We agree that this bogus error message is confusing. However, since it's preceded by an un-silenceable command line deprecation warning D9035, we believe that that should be sufficient. D9035 already says that /Wp64 shouldn't be used (although it doesn't go on to say "this option is super duper buggy, and completely unnecessary now").

In the STL, we could #error when /Wp64 is used. However, that would break customers who are still compiling with /Wp64 (despite the deprecation warning) and aren't triggering this bogus error. The STL could also emit a warning, but the compiler is already emitting D9035.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • Factually wrong: "compiling for a 64-bit target will catch the kinds of errors it was designed to catch (/Wp64 is only valid in 32-bit compiles)" ... on VS2010/SP1 you MUST specify `/Wp64` also in x64 Builds if you want to get `C4311` (which *is* extremely helpful). user13251 laso mentions this in his answer. – Martin Ba May 09 '16 at 12:15
4

/Wp64 on 32-bit builds is a waste of time. It is deprecated, and this deprecation makes sense. The way /Wp64 worked on 32-bit builds is it would look for a _w64 annotation on a type. This _w64 annotation would tell the compiler that, even though this type is 32-bits in 32-bit mode, it is 64-bits in 64-bit mode. This turned out to be really flakey, especially where templates are involved.

/Wp64 on 64-bit builds is extremely useful. The documentation (http://msdn.microsoft.com/en-us/library/vstudio/yt4xw8fh.aspx) claims that it is on by default in 64-bit builds, but this is not true. Compiler warnings C4311 and C4312 are only emitted if /Wp64 is explicitly set. Those two warnings indicate when a 32-bit value is put into a pointer, or vice-versa. These are very important for code correctness, and claim to be at warning level 1. I have found bugs in very widespread code that would have been stopped if the developers had turned on /Wp64 for 64-bit builds. Unfortunately, you also get the command line warning that you have observed. I know of no way to squelch this warning, and I have learned to live with it. On the bright side, if you build with as warnings as errors, this command line warning doesn't turn into an error.

user13251
  • 193
  • 8
  • You can enable those warnings without using `/Wp64`, with something like `/w44311 /w44312`. The documentation is misleading; what it means is that those warnings get enabled by `/Wp64`, not that they can only be enabled if `Wp64` is enabled. Sadly there's no list of "warnings which are normally only enabled when `/Wp64` is enabled" and they don't appear in the list of "warnings which are not on by default" so we're left to pick through MSDN to find them :( – Ben Hymers Oct 28 '14 at 10:46
  • @BenHymers - as far as I can tell, **on VS2010** the *only* way to get `C4311` (even on x64 build) is to specify `/Wp64`. I think user13251's advice is spot on. (`/w44311` does *not* work for me on my VS2010, nor does the corresponding `pragma warning`) – Martin Ba May 09 '16 at 12:18
  • @MartinBa - good info, thanks! I can't remember what compiler I was using in 2014 but I imagine it works the way I described in either VS2012 or VS2013... :) hopefully 2014 me wasn't just making stuff up! – Ben Hymers May 09 '16 at 15:53
  • @Ben I guess given how the docs changed for this, I think they definitely did fix this. – Martin Ba May 09 '16 at 16:23
2

Because when using the 64 Bit compiler from VS2010 the compiler does the detection of 64 bit problems automatically... this switch is from back in the day when you could try to detect 64 Bit problem running the 32 Bit compiler...

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

Yahia
  • 69,653
  • 9
  • 115
  • 144
0

You could link to the deprecation warning, but couldn't go to the /Wp64 documentation?

By default, the /Wp64 compiler option is off in the Visual C++ 32-bit compiler and on in the Visual C++ 64-bit compiler.

If you regularly compile your application by using a 64-bit compiler, you can just disable /Wp64 in your 32-bit compilations because the 64-bit compiler will detect all issues.

Emphasis added

Community
  • 1
  • 1
Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • So they're deprecating it just because it's not 100% foolproof? I imagined there must actually be something *wrong* with it, not simply the fact that it can't detect all issues (it's not like a 64-bit compiler can detect all issues either)... – user541686 Aug 24 '11 at 06:36
  • @Mehrdad - they're deprecating it because the 64-bit compiler does the same work anyway, on a non-optional basis. – Damien_The_Unbeliever Aug 24 '11 at 06:37
  • Maybe it's just me, but I don't find that convincing, sorry. – user541686 Aug 24 '11 at 06:58