Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
665 views
in Technique[技术] by (71.8m points)

visual c++ - Why is /Wp64 deprecated?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...