2010-10-30 4 views
6

nie mogę wydawać się pozbyć tego ostrzeżenia dla następującej linii kodu:Jak wyciszyć C CS0675 # ostrzegawczy: bitowym lub operator używany na argumencie znak rozszerzona

d.word[wrdIndex++] = d.GetWord(english) | (ulong)i; 

ostrzeżenie dotyczy kod po operatorze przypisania. metoda GetWord zwraca wartość ulong. Próbowałem następujące bezskutecznie:

d.word[wrdIndex++] = (d.GetWord(english) | (ulong)i); 
d.word[wrdIndex++] = d.GetWord(english) | ((ulong)i); 
d.word[wrdIndex++] = ((ulong)d.GetWord(english)) | ((ulong)i); 

Ktoś ma jakieś pomysły?

Odpowiedz

17

UPDATE: Ta kwestia była przedmiotem mojego bloga: poniedziałek, 29 listopada 2010:

http://blogs.msdn.com/b/ericlippert/archive/2010/11/29/bit-twiddling-what-does-warning-cs0675-mean.aspx

Dzięki za świetne pytanie!


można pozbyć się ostrzeżenia, najpierw myśli o ostrzeżeniu i podejmowaniu decyzji, czy kompilator jest prawo wnieść problem uwagę w pierwszej kolejności! Czy rzeczywiście otrzymasz niepoprawne wyniki od bitowego lub czy konwersja z typu podpisanego na większy znak typu unsigned - przedłużyć liczbę całkowitą?

Jeśli odpowiedź brzmi tak, to twoje rozwiązanie jest błędne. Nie usuwaj ostrzeżenia, nakłaniając kompilator do robienia niewłaściwych rzeczy bez uprzedniego ostrzeżenia. Wyeliminuj ostrzeżenie, postępując właściwie: nie używaj konwersji, która powoduje, że znak-rozszerza liczbę całkowitą.

Jeśli odpowiedź brzmi nie i chcesz rozszerzenie znak następnie rozwiązanie lub rozwiązanie Hansa passant jest prawidłowe. Jednak chciałbym umieścić komentarz w tym kodzie, ponieważ w jego obecnym brzmieniu trudno jest dostrzec, że rozszerzenie znaku jest pożądane.

+0

Kod z pewnością robi to, co powinien (i jest to właściwy sposób robienia tego, co chcę w tym przypadku, myślę) - Jestem tylko zaskoczony, że druga z 3 prób: d.GetWord (angielski) | ((ulong) i) nadal dostarcza ostrzeżenie, ponieważ ((ulong) i) jest rzutowane na ulong zanim bitowy operator OR zostanie zastosowany, prawda? –

+1

Ah, teraz rozumiem - to naprawdę całkiem sprytny kompilator, aby ostrzec mnie o tym, jak sądzę. Czy istnieje sposób na odlanie do ulong bez rozszerzenia znaku (inne niż poprzez ręczne maskowanie wierzchołka)? –

+1

Przesyłaj najpierw do uint. '(ulong) (uint) i' – CodesInChaos

2

Niestety, właśnie pozbył się go thusly:

ulong w = d.GetWord(english); 
ulong u = (ulong)i; 
d.word[wrdIndex++] = w | u; 
+0

Jak wskazano powyżej, jeśli 'i' jest ujemne, twój kod zostanie złamany (ponieważ reszta' u' będzie zawierała 0xFFFFFFFF, więc wartość 'd.GetWord (angielski)' zostanie całkowicie utracona zamiast być w połączeniu z 'i'). – MrCranky

6
int i=-1;     // =   0xFFFFFFFF 
ulong u1=(ulong)i;  // = 0xFFFFFFFFFFFFFFFF 
ulong u1a=(ulong)(long)i; // = 0xFFFFFFFFFFFFFFFF 
ulong u2=(ulong)(uint)i; // = 0x00000000FFFFFFFF 

Tak więc odlewanie z int do ulong odpowiada pierwszemu znakowi - rozszerzającemu się do (podpisanym) długim, a następnie odrzucającemu znak.

Powiązane problemy