条件运算符:从 'int ' 转换到“unsigned char”,可能会丢失数据
我有以下 C 代码:
a = (b == B1) ? A1 : A2;
a
、b
、A1
、A2
和 B1
> 均为unsigned char
类型。 A1
、A2
和 B1
都是常量。
在 VC++ 下编译时,我看到以下警告:
warning C4244: '=' : conversion from 'int ' to 'unsigned char ', possible loss of data
我不明白此警告 - 没有一个变量的类型为 int
。大概正在发生某种隐式转换,但为什么呢?
奇怪的是,以下代码(功能相同)编译时没有警告:
if (b == B1) {
a = A1;
} else {
a = A2;
}
据我所知,两个代码摘录应该是相同的。
I have the following C code:
a = (b == B1) ? A1 : A2;
a
, b
, A1
, A2
and B1
are all of type unsigned char
. A1
, A2
and B1
are all constants.
When compiling under VC++ I see the following warning:
warning C4244: '=' : conversion from 'int ' to 'unsigned char ', possible loss of data
I don't understand this warning - none of the variables are of type int
. Presumably some kind of implicit conversion is happening, but why?
Strangely, the following code (which is functionally identical) compiles with no warnings:
if (b == B1) {
a = A1;
} else {
a = A2;
}
So far as I'm aware, the two code extracts should be identical.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 C 语言中,三元
?:
运算符的算术参数要进行通常的算术转换,即在执行任何进一步计算之前将它们提升为int
。它们是否是常数并不重要。重要的是它们的类型为unsigned char
(如您所说),并且?:
下的unsigned char
始终首先提升。基本上,C 语言从不执行任何小于int
的类型的计算。所有较小的值都会首先转换为int
。您的情况也会发生这种情况。基本上,您的
内容被 C 语言解释为
,这就是您收到警告的原因。同样,
A1
和A2
是常量的事实没有任何作用。。
右侧不会进行积分提升,这就是这里没有警告的原因 此外,在这种简单的情况下(直接赋值),即使
A1
被显式声明为int
常量,大多数编译器如果可以看到该常量是在目标类型unsigned char
的范围内。?:
的情况更为复杂,因此编译器可能会恢复到通用行为并发出警告。In C language arithmetic arguments of ternary
?:
operator are subjected to usual arithmetic conversions, i.e. they are promoted toint
before any further computations are performed. It doesn't really matter whether they are constants or not. What matters is that they have typeunsigned char
(as you said) andunsigned char
under?:
is always promoted first. Basically, C language never performs any computations in types smaller thanint
. Everything smaller is converted toint
first.This is what happens in your case as well. Basically, your
is interpreted by C language as
and this is why you get the warning. Again, the fact that
A1
andA2
are constants plays no role whatsoever.The
does not subject the right-hand side to integral promotion, which is why there's no warning here. Moreover, in this trivial case (direct assignment) even if
A1
was explicitly declared as anint
constant, most compilers would not issue a warning if they could see that the constant is in range of the target typeunsigned char
. The case with?:
is more complicated, so the compilers might revert to the generic behavior and issue a warning.尽管功能相同,但这两个代码并不完全相同。
你看,当你使用三元运算符时,这就是
条件 ? true_value : false_value
,编译器尝试在值之间推断出最佳的可能类型。由于 A1 和 A2 是常量(正如您在 OP 中所述),编译器将其位置替换为实际值,完全忽略数据类型,将两者呈现为整数。
因此需要转换结果,如下所示:
Although functionally the same, both codes are not quite equals.
You see, when you use a ternary operator, that is the
condition ? true_value : false_value
, the compiler tries to infer between the values the best possible type.Because A1 and A2 are constant (as you state in the O.P.) the compiler replaces their position by their actual values, ignoring completely the data type, rendering both as integers.
Hence the need to cast the result, as such:
我相信这是因为子语句中没有右值——它们在词法分析器中自动转换为 int 。上面的代码应该解决警告消息并且对结果代码没有影响。
I believe this is because there is no rvalues in the sub statements -- they get auto converted to int in the lexer. The code above should solve the warning message and have no effect on the resulting code.