2015-10-07 28 views
5

mam linię kodu, który daje mi komunikat ostrzegawczy (CS0675) w VS2015, ale nie w 2013 rokuBłąd w kompilatorze lub nieporozumieniu? Lub operator na spodenkach

shortValue |= (short)anEnum; 

Ostrzeżenie CS0675 bitowym lub operatora wykorzystywane na steru- rozszerzony operand; Najpierw należy rozważyć rzutowanie na mniejszy, niepodpisany typ. Kompilator niejawnie rozszerzył i rozszerzył znak zmiennej, a następnie użył wartości wynikowej w bitowej operacji OR. Może to spowodować nieoczekiwane zachowanie.

Oczywiście to, co się dzieje, to enum i skrót są rozszerzane na int, operator lub stosowane, a następnie wynik przypisany wynik do skrótu.

Po zmianie kodu na shortValue = shortValue | (short)anEnum; pojawia się błąd kompilatora CS0266. Ale bitowe OR powinno być ważne dla szortów (w obu przypadkach uważam). Jeśli umieścisz kursor myszy nad ikoną |, pokaże się jako operator int, czy coś pomijam, czy powinienem zgłosić to jako błąd?

PS: Wiem, że mogę wyeliminować ostrzeżenie/błąd, używając = zamiast |= i rzutując wynik na krótki.

+1

Zobacz także [Operatory bitowe lub operator używane w operandzie rozszerzonym znakiem w Visual Studio 2015] (http://stackoverflow.com/questions/31542256/) i inne wątki. –

+0

To jest błąd w VS2015 i zostanie naprawiony w aktualizacji VS2015 1. Zobacz https://github.com/dotnet/roslyn/issues/4027. –

Odpowiedz

5

Jeśli spojrzeć na specyfikacje C# (szczególnie w "Integer operatorów logicznych") zobaczysz, że tam jest tylko definicja int, uint, long, ulong dla operatora logicznego OR:

int operator |(int x, int y); 
uint operator |(uint x, uint y); 
long operator |(long x, long y); 
ulong operator |(ulong x, ulong y); 

również w Bit twiddling: What does warning CS0675 mean? Eric Lippert stwierdza:

„Istnieją bitowym lub podmioty określone na int, uint, long i ulong "

operator jest ważny przez short, ale tylko w tym sensie, że krótki wartość może zostać przedłużony do int. Wartość zwracana tego operatora jest jednak (co najmniej) równa int.

Tak, technicznie rzecz biorąc, według specyfikacji, to nie wydaje się być problem, jak za pomocą |= powoduje przedłużenia podpisanej wartość int, który daje ostrzeżenie i regularne | wyniki w int który musi być odrzucony, aby zostać przypisanym do short.

Jednak, ponieważ kompilator może w rzeczywistości wiemy, że oba argumenty są pierwotnie short s, zarówno Kup Rozszerzoną do int a wynik zostanie ostatecznie zapisane z powrotem do short to naprawdę nie ma znaczenia, że ​​argumenty są rozszerzone . Rozszerzenie zostanie utracone przez obsadę od int do short.

Tak więc albo kompilator VS2013 był sprytniejszy z ostrzeżeniami niż VS2015, albo VS2015 naprawiał błąd i ostrzegał, gdzie nie udało się VS2013. Tylko osoby odpowiedzialne za kompilator mogą na to odpowiedzieć, ale zakładam, że to rzeczywiście błąd (EDYCJA: and it is).

+0

Myślę, że i tak zgłoszę to jako błąd, ponieważ nie ma sposobu na użycie | = bez ostrzeżenia lub błędu w 2015 r., Ale 2013 był z niego zadowolony (więc albo był to błąd w 2013 r., Albo celowo stłumiony błąd i podejrzewam, że później). – jmoreno

+0

@jmoreno Naprawdę nie nazwałbym tego błędem, ale zgadzam się, że VS2013 jest właśnie tutaj, a VS2015 nie jest. Zaktualizowałem nieco odpowiedź, aby to wyjaśnić. – i3arnon

+2

@jmoreno I najwyraźniej zostało naprawione: https://github.com/dotnet/roslyn/issues/4027 – i3arnon