На самом деле 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.