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

时间:2015-07-21 14:42:29

标签: c# bit-manipulation visual-studio-2015 roslyn

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

  

CS0675在符号扩展操作数上使用的Bitwise或运算符;考虑   首先转换为较小的无符号类型

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

short a = 0;
int b = 0;

a |= (short)b;

现在,我已阅读this SO question,我已在此问题上阅读了Eric Lippert's blog post,我很快就阅读了sign extension,但我的理解是,当您从有符号数字类型,由较少的位数组成,具有较大的位数,例如shortint

但是因为我从int投射到short,所以如果我没有弄错的话,不会发生任何符号扩展。事实上,这不会在早期版本的Visual Studio中发出警告,这让我相信这必定是Visual Studio 2015编译器(Roslyn)中的一个错误。我是否误解了符号扩展和/或编译器如何在这里工作,或者这很可能是编译器错误?

更新

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

2 个答案:

答案 0 :(得分:10)

签名扩展 正在发生,但可能不是出于明显的原因,而不是令人担忧的方式,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#编译器团队成员,看看我错过了什么:)

答案 1 :(得分:10)

这只是一个错误。在VS2015开发中很晚才添加检测和报告此错误的代码(请参阅https://github.com/dotnet/roslyn/issues/909https://github.com/dotnet/roslyn/pull/2416),与VS2013相比,它检测到的案例太多。现在有一个错误报告(https://github.com/dotnet/roslyn/issues/4027)来修复它。