我刚尝试安装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,但我的理解是,当您从有符号数字类型,由较少的位数组成,具有较大的位数,例如short
到int
。
但是因为我从int
投射到short
,所以如果我没有弄错的话,不会发生任何符号扩展。事实上,这不会在早期版本的Visual Studio中发出警告,这让我相信这必定是Visual Studio 2015编译器(Roslyn)中的一个错误。我是否误解了符号扩展和/或编译器如何在这里工作,或者这很可能是编译器错误?
Jon Skeet指出实际上确实发生了符号扩展,因为|
运算符没有为short
定义,所以在结果出现之前有int
的隐式转换再次回到short
。但是,编译器不应该发出此警告,因为强制转换是无害的。 Roslyn编译器中存在一个错误,如接受的答案所述。
答案 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/909和https://github.com/dotnet/roslyn/pull/2416),与VS2013相比,它检测到的案例太多。现在有一个错误报告(https://github.com/dotnet/roslyn/issues/4027)来修复它。