编译器的Bug还是误解?或者对短裤的运算符
本文关键字:运算符 或者 误解 Bug 编译器 | 更新日期: 2023-09-27 18:16:35
我有一行代码,在VS2015中给我一个警告消息(CS0675),但不是在2013年。
shortValue |= (short)anEnum;
警告CS0675位或操作符在符号扩展操作数上使用;首先考虑转换为较小的无符号类型。编译器隐式扩展和符号扩展变量,然后使用位或运算的结果值。这可能导致意想不到的行为。
显然,现在的情况是enum和short类型被扩展为int类型,应用or操作符,然后将结果赋值给short类型。
如果我将代码更改为shortValue = shortValue | (short)anEnum;
,我会得到一个编译器错误CS0266。但是按位或应该对短裤有效(我相信在这两种情况下)。如果我把鼠标悬停在|
上,它显示为一个int操作符,我错过了什么,或者我应该报告这是一个bug?
PS:我知道我可以通过使用=
而不是|=
来消除警告/错误,并将结果转换为短。
如果你看一下c#规范(特别是在"整数逻辑运算符"中),你会发现只有int
, uint
, long
, ulong
的逻辑或运算符定义:
int operator |(int x, int y);
uint operator |(uint x, uint y);
long operator |(long x, long y);
ulong operator |(ulong x, ulong y);
另外,在Bit twiddling中:警告CS0675是什么意思?Eric Lippert说:
"
int
,uint
,long
和ulong
上定义了位或运算符"
运算符对short
有效,但仅在短值可以扩展到int
的意义上有效。然而,该操作符的返回值(至少)是int
。
所以,从技术上讲,根据规范,这似乎不是一个bug,因为使用|=
确实将带符号的值扩展为int,这会给出警告,而常规的|
会导致int
,需要将其转换为分配给short
。
然而,由于编译器实际上可以知道两个操作数最初都是short
,它们都扩展到int
,并且结果最终将存储回short
,因此操作数扩展并不重要。从int
转换到short
时,扩展将丢失。
所以,要么VS2013编译器的警告比VS2015更聪明,要么VS2015修复了一个错误,并在VS2013失败的地方发出警告。只有编译器背后的人可以回答这个问题,但我认为这确实是一个错误(编辑:它是)。