Побитовое или оператор, используемый в расширенном расширении в Visual Studio 2015

Я просто попытался установить Visual Studio 2015, и, пытаясь скомпилировать старый проект, я получил предупреждение

CS0675 Побитовое или оператор, используемый в операнде расширенного знака; подумайте о том, чтобы сначала наложить на меньший неподписанный тип

за кусок кода, который не дает того же предупреждения при компиляции в Visual Studio 2013. Я узнал, что все, что требуется для воспроизведения, – это очень простой код:

short a = 0; int b = 0; a |= (short)b; 

Теперь я прочитал этот вопрос SO , я прочитал сообщение в блоге Эрика Липперта по этой проблеме, и я быстро прочитал о расширении знака , но я понимаю, что расширение знака происходит, когда вы отбрасываете из числа подписанных номеров, состоящего из меньшего числа бит к одному с большим количеством битов, например, например, short to int .

Но поскольку я отбрасываю от int до short , расширение знака не должно происходить, если я не ошибаюсь. Тот факт, что это не выдает предупреждения в более ранних версиях Visual Studio, приводит меня к мысли, что это должно быть ошибкой в ​​компиляторе Visual Studio 2015 (Roslyn). Я не понимаю, как работает расширение знака и / или компилятор, или это, скорее всего, ошибка компилятора?

Обновить

Джон Скит отметил, что на самом деле действительно есть расширение знака, так как | оператор не определен для short и поэтому есть неявный приведение к int до того, как результат снова будет возвращен к short . Однако компилятор не должен был выдавать это предупреждение, так как литье безвредно. В компиляторе Roslyn произошла ошибка, как указано в принятом ответе.

Это всего лишь ошибка. Код для обнаружения и сообщения об этой ошибке был добавлен очень поздно в разработке VS2015 (см. https://github.com/dotnet/roslyn/issues/909 и https://github.com/dotnet/roslyn/pull/2416 ) и он обнаруживает слишком много случаев по сравнению с VS2013. В настоящее время существует отчет об ошибке ( https://github.com/dotnet/roslyn/issues/4027 ), чтобы исправить это.

Расширение знака происходит, но, возможно, не по понятной причине, а не в беспокойстве, ИМО.

Этот код:

 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 

Учитывая, что | оператор работает с кастами, это выглядит совершенно безвредно для меня. Я не уверен, буду ли я называть его ошибкой компилятора, но это определенно выглядит для меня неидеальным поведением. Будет ли команда команды компилятора ping C # видеть то, что я пропустил 🙂