2011-08-24 22 views

Odpowiedz

15

myślę że /Wp64 jest przestarzała głównie dlatego kompilacji za cel 64-bitowym złapie rodzaje błędów zostało zaprojektowane, aby złapać (/ Wp64 jest ważna tylko w 32-bitowych kompilacji). Ta opcja została dodana, gdy pojawiły się 64-bitowe obiekty docelowe, aby ułatwić migrację swoich programów do wersji 64-bitowych i pomóc w wykryciu kodu, który nie był "bezpieczny pod kątem 64-bitów".

Oto przykład od rodzaju problemy z /Wp64 że Microsoft po prostu nie jest zainteresowany ustaleniem - prawdopodobnie słusznie (od http://connect.microsoft.com/VisualStudio/feedback/details/502281/std-vector-incompatible-with-wp64-compiler-option):

Faktycznie, STL nie jest celowo niezgodne z /Wp64, ani nie jest on całkowicie i bezwarunkowo niezgodny z /Wp64. Podstawowy problem polega na tym, że /Wp64 oddziałuje wyjątkowo źle z szablonami , ponieważ __w64 nie jest w pełni zintegrowany z systemem typu. Dlatego jeśli vector<unsigned int> zostanie utworzony przed vector<__w64 unsigned int>, to oba będą zachowywać się jak vector<unsigned int> i na odwrót. Na x86, SOCKET jest typedef dla __w64 unsigned int. To nie jest oczywiste, ale vector<unsigned int> jest tworzony przed Twoim vector<SOCKET>, ponieważ vector<bool> jest wspierany (w naszej implementacji ) przez vector<unsigned int>.

Poprzednio (w wersji VC9 i wcześniejszych) ta zła interakcja między szablonami i szablonami powodowała fałszywe ostrzeżenia. Jednak w VC10 zmiany na STL pogorszyły sytuację. Teraz, gdy vector::push_back() otrzymuje się jako element samego wektora, oblicza on indeks elementu przed wykonaniem innej pracy. Indeks ten jest uzyskiwany poprzez odjęcie adresu elementu od początku wektora.W swoim repro, wymaga to odjęcia const SOCKET * - unsigned int *. (Ten ostatni jest unsigned int *, a nie SOCKET * ze względu na wcześniej opisany błąd . To/powinien/wywołać fałszywe ostrzeżenie, mówiąc: "Odejmuję wskaźniki wskazujące ten sam typ na x86, ale na różnych typów na x64 ". Istnieje jednak DRUGI błąd tutaj, w którym /Wp64 zostaje naprawdę zdezorientowany i uważa, że ​​jest to trudny błąd (podczas gdy dodanie stałej do unsigned int *).

Zgadzamy się, że ten fałszywy komunikat o błędzie jest mylący. Jednak od jest poprzedzone nieumiejętnym ostrzeżeniem o przestarzałości, ostrzeżeniem D9035, uważamy, że to powinno wystarczyć. D9035 już mówi: , którego nie należy używać, ponieważ nie należy używać /Wp64 (chociaż nie mówi się "ta opcja jest superplikowana, a teraz zupełnie niepotrzebna").

W STL mogliśmy użyć #error, gdy używamy /Wp64. Jednak to oznaczałoby, że klienci, którzy wciąż kompilują się przy pomocy /Wp64, nadal będą kompilować się z /Wp64 (pomimo ostrzeżenia o wycofaniu w postaci) i nie powodują tego fałszywego błędu. STL może również emitować ostrzeżenie, ale kompilator już emituje D9035.

+0

Ahhh teraz * to * jest przekonującą, rozsądną odpowiedzią !! Wielkie dzięki za opublikowanie! :) +1 – Mehrdad

+0

W rzeczywistości błędne: "kompilacja dla 64-bitowego celu złapie rodzaje błędów, które zostały zaprojektowane do przechwycenia (/ Wp64 jest poprawny tylko w kompilacjach 32-bitowych)" ... w VS2010/SP1 MUSISZ określić '/ Wp64' również w x64 Buduje, jeśli chcesz uzyskać' C4311' (który * jest * bardzo pomocny). user13251 laso wspomina o tym w swojej odpowiedzi. –

2

Ponieważ podczas korzystania z kompilatora 64 bit z VS2010 kompilator wykonuje detekcję 64 bitowych problemów automatycznie ... ten przełącznik jest z powrotem w dzień, kiedy można spróbować wykryć problemu 64 bit działa kompilator 32 bit ...

Zobacz http://msdn.microsoft.com/en-us/library/yt4xw8fh%28v=VS.100%29.aspx

+0

Nieprawidłowy. Co najmniej * dla VS2010. Dokumenty są zepsute. –

0

Można utworzyć łącze do ostrzeżenia o wycofaniu, ale nie można przejść do dokumentacji /Wp64?

Domyślnie opcja kompilator/Wp64 jest wyłączony w Visual C++ 32-bitowego kompilatora oraz w Visual C++ 64-bitowego kompilatora.

Jeśli regularnie kompilujesz aplikację przy użyciu 64-bitowego kompilatora, możesz po prostu wyłączyć/Wp64 w 32-bitowych kompilacjach , ponieważ 64-bitowy kompilator wykryje wszystkie problemy.

Podkreślenie

+0

Czyli nie są one w 100% niezawodne? Wyobrażałem sobie, że musi być coś * nie tak z nim, nie tylko fakt, że nie może wykryć wszystkich problemów (to nie jest tak, że 64-bitowy kompilator może wykryć wszystkie problemy) ... – Mehrdad

+0

@Mebradzki - one są przestarzałe, ponieważ 64-bitowy kompilator robi to samo i tak w sposób nieobowiązkowy. –

+0

Może to tylko ja, ale nie przekonuje mnie to, przepraszam. – Mehrdad

4

/Wp64 na kompilacjach 32-bitowych to strata czasu. Jest przestarzałe, a ta deprecjacja ma sens. Sposób/Wp64 działał na 32-bitowych kompilacjach, szukał adnotacji _w64 na typie. Ta adnotacja _w64 powie kompilatorowi, że chociaż ten typ jest 32-bitowy w trybie 32-bitowym, to jest 64-bitowy w trybie 64-bitowym. Okazało się, że jest naprawdę flakey, szczególnie tam, gdzie są zaangażowane szablony.

/Wp64 na kompilacjach 64-bitowych jest niezwykle przydatny. Dokumentacja (http://msdn.microsoft.com/en-us/library/vstudio/yt4xw8fh.aspx) twierdzi, że jest domyślnie włączona w kompilacjach 64-bitowych, ale nie jest to prawdą. Ostrzeżenia dotyczące kompilatora C4311 i C4312 są emitowane tylko wtedy, gdy/Wp64 jest jawnie ustawiony. Te dwa ostrzeżenia wskazują, kiedy wartość 32-bitowa zostanie umieszczona w wskaźniku lub odwrotnie. Są one bardzo ważne dla poprawności kodu i twierdzą, że są na poziomie ostrzegawczym 1. Znalazłem błędy w bardzo rozpowszechnionym kodzie, który zostałby zatrzymany, gdyby programiści włączyli/Wp64 dla wersji 64-bitowych. Niestety otrzymujesz również ostrzeżenie z linii poleceń, które zaobserwowałeś. Nie znam żadnego sposobu, aby uciszyć to ostrzeżenie i nauczyłem się z tym żyć. Z drugiej strony, jeśli budujesz z ostrzeżeniami jako błędami, to ostrzeżenie linii poleceń nie zmienia się w błąd.

+0

Możesz włączyć te ostrzeżenia bez użycia '/ Wp64', z czymś takim jak'/w44311/w44312'. Dokumentacja wprowadza w błąd; oznacza to, że te ostrzeżenia są włączane przez '/ Wp64', a nie, że mogą być włączone tylko wtedy, gdy włączone jest' Wp64'.Niestety nie ma listy "ostrzeżeń, które są normalnie włączane tylko po włączeniu opcji'/Wp64 "i nie pojawiają się na liście" ostrzeżeń, które nie są domyślnie włączone ", więc możemy pozostawić wybór przez MSDN, aby znaleźć one :( –

+0

@BenHymers - o ile mogę powiedzieć, ** na VS2010 ** jedynym * sposobem na uzyskanie 'C4311' (nawet na kompilacji x64) jest określenie'/Wp64'. Myślę, że user13251 ma rade on. ('/ w44311' does * not * działa dla mnie na moim VS2010, ani odpowiadające mu' pragma warning') –

+0

@MartinBa - dobre informacje, dziękuję! Nie pamiętam, jakiego kompilatora używałem w 2014 roku, ale ja wyobraź sobie, że działa tak, jak opisałem w VS2012 lub VS2013 ... :) mam nadzieję, że 2014 rok nie był po prostu tworzeniem rzeczy! –

Powiązane problemy