Битовый или оператор, используемый для операнда с расширенным знаком в Visual Studio 2015
Я только что попытался установить Visual Studio 2015, и при попытке скомпилировать старый проект, я получил предупреждение
CS0675 Битовый или оператор, используемый в операнде с расширенным знаком; сначала рассмотрите приведение к меньшему типу без знака
для фрагмента кода, который не выдает того же предупреждения при компиляции в Visual Studio 2013. Я обнаружил, что все, что требуется для воспроизведения, это очень простой код:
short a = 0;
int b = 0;
a |= (short)b;
Теперь я прочитал этот вопрос, я прочитал сообщение Эрика Липперта в блоге по этой проблеме, и я быстро прочитал о расширении знака, но я понимаю, что расширение знака происходит, когда вы применяете тип числа со знаком, состоящий из меньшего числа. битов в один с большим количеством битов, таких как short
в int
например.
Но так как я кастую из int
к short
Расширение знака не должно произойти, если я не ошибаюсь. Тот факт, что это не выдает предупреждение в более ранних версиях Visual Studio, приводит меня к мысли, что это должно быть ошибкой в компиляторе Visual Studio 2015 (Roslyn). Я неправильно понимаю, как расширение знака и / или компилятор работает здесь, или это, скорее всего, ошибка компилятора?
Обновить
Джон Скит отметил, что на самом деле расширение знака происходит с |
оператор не определен для short
и поэтому есть неявное приведение к int
прежде чем результат будет возвращен к short
снова. Тем не менее, компилятор не должен был выдавать это предупреждение, поскольку приведение безвредно. Была ошибка в компиляторе Roslyn, как указано в принятом ответе.
2 ответа
Это просто ошибка. Код для обнаружения и сообщения об этой ошибке был добавлен очень поздно в разработке VS2015 (см. https://github.com/dotnet/roslyn/issues/909 и https://github.com/dotnet/roslyn/pull/2416). и он обнаруживает слишком много случаев по сравнению с VS2013. Теперь есть сообщение об ошибке ( https://github.com/dotnet/roslyn/issues/4027), чтобы исправить это.
Расширение знака происходит, но, возможно, не по очевидной причине, и не в тревожном смысле, IMO.
Этот код:
a |= (short) b;
эквивалентно:
// No warning here... (surprisingly, given that `a` is being sign-extended...)
a = (short) (a | (short) b);
Что эквивалентно:
// No warning here...
a = (short) ((int) a | (int) (short) b;
поскольку |
оператор не определен для short
операнды в любом случае. Оба операнда повышены до int
затем результат возвращается к short
,
Непонятно, почему компилятор решает предупредить в этом случае, но происходит расширение знака... хотя и безвредно.
Обратите внимание, что вы получите то же предупреждение, если нет int
переменные задействованы вообще:
short a = 10;
short b = 20;
a |= b; // CS0675
Учитывая то, что |
оператор работает с приведениями, это выглядит для меня совершенно безобидно. Я не уверен, назову ли я это ошибкой компилятора, но это определенно выглядит как неидеальное поведение для меня. Будет пинговать членов команды C#, чтобы увидеть, что я пропустил:)