Почему флаг /Wp64
в Visual С++ устарел?
cl: Предупреждение командной строки D9035:
опция "Wp64" устарела и будет удалена в будущей версии
Почему флаг /Wp64
в Visual С++ устарел?
cl: Предупреждение командной строки D9035:
опция "Wp64" устарела и будет удалена в будущей версии
Я думаю, что /Wp64
устарел, главным образом потому, что компиляция для 64-битной цели поймает типы ошибок, которые она была предназначена для catch (/Wp64 действителен только в 32-битных компиляторах). Опция была добавлена обратно, когда появились 64-битные цели, чтобы помочь людям перенести свои программы на 64-разрядные и помочь обнаружить код, который не был "чистым 64-битным".
Вот пример проблем с /Wp64
, которые Microsoft просто не интересует фиксацией - возможно, правильно (от 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
является typedef для__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
действительно запутывается и думает, что это трудная ошибка (в то время как добавляя константу кunsigned int *
).Мы согласны с тем, что это ложное сообщение об ошибке запутывает. Однако, поскольку ему предшествует предупреждение об отсутствии устаревания командной строки D9035, мы считаем, что этого должно быть достаточно. D9035 уже говорит что
/Wp64
не должен использоваться (хотя он не продолжает говорить "это опция является супер-пуперной ошибкой и теперь совершенно ненужной" ).В STL мы могли бы
#error
использовать/Wp64
. Однако это разбить клиентов, которые все еще компилируются с помощью/Wp64
(несмотря на предупреждение об утомлении) и не запускают эту фальшивую ошибку. STL также может выдавать предупреждение, но компилятор уже испускает D9035.
/Wp64 на 32-битных сборках - пустая трата времени. Он устарел, и это обесценивание имеет смысл. Способ /Wp 64 работал на 32-битных сборках, он будет искать аннотацию _w64 для типа. Эта аннотация _w64 сообщила бы компилятору, что, хотя этот тип 32-битный в 32-битном режиме, он 64-битный в 64-битном режиме. Это оказалось действительно ошибочным, особенно там, где задействованы шаблоны.
/Wp64 в 64-битных сборках чрезвычайно полезен. Документация (http://msdn.microsoft.com/en-us/library/vstudio/yt4xw8fh.aspx) утверждает, что она включена по умолчанию в 64-битных сборках, но это неверно. Предупреждения компилятора C4311 и C4312 выдаются только в том случае, если /Wp 64 явно установлен. Эти два предупреждения указывают, когда 32-битное значение помещается в указатель или наоборот. Они очень важны для правильности кода и утверждают, что они находятся на уровне предупреждения 1. Я обнаружил ошибки в очень распространенном коде, который был бы остановлен, если разработчики включили /Wp 64 для 64-битных сборок. К сожалению, вы также получаете предупреждение о командной строке, которое вы заметили. Я не знаю, как подавить это предупреждение, и я научился жить с ним. С яркой стороны, если вы создаете с предупреждениями как ошибки, это предупреждение командной строки не превращается в ошибку.
Потому что при использовании 64-битного компилятора из VS2010 компилятор автоматически обнаруживает 64-битные проблемы... этот коммутатор находится в обратном порядке в тот день, когда вы можете попытаться обнаружить 64-разрядную проблему с 32-битным компилятором...
См. http://msdn.microsoft.com/en-us/library/yt4xw8fh%28v=VS.100%29.aspx
Вы можете ссылаться на предупреждение об устаревании, но не могли перейти в /Wp64
документацию?
По умолчанию параметр компилятора /Wp 64 отключен в 32-битном компиляторе Visual С++ и включен в 64-разрядный компилятор Visual С++.
Если вы регулярно компилируете свое приложение с помощью 64-битного компилятора, вы можете просто отключить /Wp 64 в 32-разрядных компиляциях , потому что 64-разрядный компилятор обнаружит все проблемы.
Добавлен акцент