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

Han*_*son 13 c# bit-manipulation roslyn visual-studio-2015

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

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

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

short a = 0;
int b = 0;

a |= (short)b;
Run Code Online (Sandbox Code Playgroud)

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

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

更新

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

Jon*_*eet 10

标志扩展正在发生,但可能不是出于明显的原因,而不是令人担忧的方式,IMO.

这段代码:

a |= (short) b;
Run Code Online (Sandbox Code Playgroud)

相当于:

// No warning here... (surprisingly, given that `a` is being sign-extended...)
a = (short) (a | (short) b);
Run Code Online (Sandbox Code Playgroud)

这相当于:

// No warning here...
a = (short) ((int) a | (int) (short) b;
Run Code Online (Sandbox Code Playgroud)

因为无论如何|都没有为short操作数定义运算符.两个操作数都被提升为int,然后结果被强制转换为short.

目前尚不清楚为什么编译器决定在这种情况下,警告,但有发生符号扩展......尽管是在一种无害的方式.

请注意,如果根本不int涉及任何变量,则会收到相同的警告:

short a = 10;
short b = 20;
a |= b; // CS0675
Run Code Online (Sandbox Code Playgroud)

鉴于|操作员使用演员表的方式,这看起来对我来说完全无害.我不确定我是否称它为编译器错误,但它对我来说肯定是非理想的行为.请ping C#编译器团队成员,看看我错过了什么:)

  • @dasblinkenlight:我实际上误解了这个问题,并且稍微改变了我的回答.我同意,这有点奇怪. (2认同)

Nea*_*ter 10

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