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

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

CS0675按位或运算符用于符号扩展操作数; 首先考虑转换为较小的无符号类型

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

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

现在,我已经阅读了这个问题 ,我已经阅读了Eric Lippert关于这个问题的博文 ,我很快就读到了符号扩展 ,但我的理解是当你从一个由较小数字组成的带符号数字类型进行转换时会发生符号扩展比特到具有更多比特数的比特,例如shortint

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

更新

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

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

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