Ответ 1
Я думаю, что /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.