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

本文关键字:操作数 运算符 位或 扩展操作 扩展 Studio Visual 2015 符号 | 更新日期: 2023-09-27 18:03:53

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

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

表示在Visual Studio 2013中编译时不会给出相同警告的一段代码。我发现复制所需要的只是这段非常简单的代码:

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

现在,我已经阅读了这个SO问题,我已经阅读了Eric Lippert关于这个问题的博客文章,我很快就阅读了符号扩展,但我的理解是,符号扩展发生在你从一个由较少位数组成的有符号数类型转换为一个具有较多位数的数字类型时,例如shortint

但是因为我是从intshort的铸造,如果我没有弄错的话,没有符号扩展应该发生。事实上,在早期版本的Visual Studio中没有发出警告,这让我相信这一定是Visual Studio 2015编译器中的一个错误。我是否误解了sign扩展和/或编译器在这里的工作方式,或者这很可能是编译器的错误?

更新

Jon Skeet指出,实际上确实发生了符号扩展,因为|操作符没有为short定义,因此在结果再次强制转换回short之前,隐式强制转换为int。然而,编译器不应该发出这个警告,因为强制转换是无害的。在Roslyn编译器中有一个bug,在接受的答案中指出。

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

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

符号扩展正在发生,但可能不是因为明显的原因,也不是以一种令人担忧的方式,我认为

这个代码:

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#编译器团队成员看看我错过了什么:)