Visual Studio 2015 中用于符号扩展操作数的按位或运算符

Bitwise-or operator used on a sign-extended operand in Visual Studio 2015

我刚刚尝试安装 Visual Studio 2015,在尝试编译一个旧项目时,我收到了警告

CS0675 Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first

对于在 Visual Studio 2013 年编译时没有给出相同警告的一段代码。我发现重现所需的只是这个非常简单的代码:

short a = 0;
int b = 0;

a |= (short)b;

现在,我已阅读 this SO question, I have read Eric Lippert's blog post on this issue, and I quickly read up on sign extension,但我的理解是,当您从包含较少位数的有符号数类型转换为包含较多位数的有符号数类型时,会发生符号扩展,例如例如 shortint

但是由于我是从 int 转换为 short,所以如果我没记错的话,应该不会发生符号扩展。事实上,这在 Visual Studio 的早期版本中没有发出警告,这让我相信这一定是 Visual Studio 2015 编译器 (Roslyn) 中的一个错误。我是否误解了符号扩展 and/or 编译器在这里的工作方式,或者这很可能是编译器错误?

更新

Jon Skeet 指出实际上确实发生了符号扩展,因为 | 运算符没有为 short 定义,所以在 int 之前有一个隐式转换结果再次返回 short 。但是,编译器不应该发出此警告,因为转换是无害的。正如已接受的答案中指出的那样,Roslyn 编译器中存在错误。

符号扩展 正在发生,但可能不是出于明显的原因,也不是以令人担忧的方式,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

考虑到 | 运算符与转换一起使用的方式,这对我来说看起来完全无害。我不确定我是否会称它为编译器 bug,但它对我来说绝对不是理想的行为。将 ping C# 编译器团队成员以查看我错过了什么:)

这只是一个错误。检测和报告此错误的代码是在 VS2015 开发的后期添加的(参见 https://github.com/dotnet/roslyn/issues/909 and https://github.com/dotnet/roslyn/pull/2416) and it detects too many cases compared to VS2013. There is now a bug report (https://github.com/dotnet/roslyn/issues/4027)以修复此问题。