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.