编译器中的错误或误解?或短裤上的操作员

时间:2015-10-07 19:33:02

标签: c# bitwise-operators roslyn c#-6.0

我有一行代码在VS2015中给出了警告信息(CS0675),但在2013年没有。

shortValue |= (short)anEnum;
  

警告CS0675在符号扩展操作数上使用按位或运算符;   首先考虑转换为较小的无符号类型。编译器   隐式扩展并对变量进行符号扩展,然后使用   以按位OR运算得到的值。这可能导致   出乎意料的行为。

显然正在发生的是enum和short被扩展为int,or运算符,然后结果将结果赋给short。

如果我将代码更改为shortValue = shortValue | (short)anEnum;,我会收到编译器错误CS0266。但是按位OR应该对短路有效(在我认为的两种情况下)。如果我将鼠标悬停在它显示为int运算符的|上,我是否遗漏了某些内容,或者我应该将其报告为错误?

PS:我知道我可以使用=代替|=消除警告/错误,并将结果转换为简短。

1 个答案:

答案 0 :(得分:5)

如果您查看C#规范(特别是“整数逻辑运算符”),您会发现intuintlong,{{1对于逻辑OR运算符:

ulong

另外,在Bit twiddling: What does warning CS0675 mean? Eric Lippert中指出:

  

“在int operator |(int x, int y); uint operator |(uint x, uint y); long operator |(long x, long y); ulong operator |(ulong x, ulong y); intuintlong上定义了按位或运算符”

运算符对ulong有效,但仅限于短值可以扩展到short的意义。但是,该运算符的返回值是(至少)int

所以,从技术上讲,根据规范,这似乎不是一个错误,因为使用int会将签名值扩展为int,这会产生警告和常规|=结果在|中,需要将其下放以分配给int

但是,因为编译器实际上可以知道两个操作数最初都是short,所以两者都扩展到short,结果最终会被存储回来int操作数扩展并不重要。从shortint的演员阵容将丢失该扩展程序。

因此,VS2013编译器的警告比VS2015编译器更智能,或VS2015修复了一个错误,并警告VS2013失败的地方。只有编译器背后的人才能回答这个问题,但我认为这确实是一个错误(编辑:and it is)。