Подтвердить что ты не робот

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

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

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

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

short a = 0;
int b = 0;

a |= (short)b;

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

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

Update

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

Ответ 1

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

Ответ 2

Расширение знака происходит, но, возможно, не по понятной причине, а не в беспокойстве, 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

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