在将无符号字符转换为整数类型的背景下发生了什么?
|
今天,我从切换块中得到了一些奇怪的行为,特别是我正在从文件中读取一个字节,并将其与某些十六进制值进行比较(文本文件编码问题,没什么大不了的)。该代码看起来像:
char BOM[3] = {0};
b_error = ReadFile (iNCfile, BOM, 3, &lpNumberOfBytesRead, NULL);
switch ( BOM[0] ) {
case 0xef: {
// Byte Order Marker Potentially Indicates UTF-8
if ( ( BOM[1] == 0xBB ) && ( BOM[2] == 0xBF ) ) {
iNCfileEncoding = UTF8;
}
break;
}
}
尽管调试看起来还可以,但这没有用。我意识到该开关将值提升为整数,一旦单击到位,我就可以在case语句中使用0xffffffef进行匹配。当然,正确的解决方案是使BOM []无符号,现在一切都按预期进行了提升和比较。
有人可以简要解释一下char-> int促销产生了0xffffffef而不是0x000000ef的情况吗?
没有找到相关结果
已邀请:
5 个回复
杭难插
负值,作为
条件,该值升为与required3 required值相同的负
值。 C ++ 98§6.4.2/ 2 进行整体促销。 然后,对于您的32位C ++编译器,ѭ4interpreted被解释为
文字,因为对于32位
而言,它太大了。 C ++ 98 2.13.1 / 2 如果是八进制或十六进制,并且没有后缀,则在 可以表示为:
,
,
,
。 现在,对于“ 11”标签, C ++ 98§6.4.2/ 2 整数常量表达式(5.19)隐式转换为提升的 开关条件的类型。 在您的情况下,对于带符号的目标类型,转换的结果是正式实现定义的,方法是 C ++ 98§4.7/ 3 如果目标类型是带符号的,则该值可以表示,则保持不变 在目标类型(和位域宽度)中;否则,值为 实现定义的。 但是实际上,几乎所有编译器都使用二进制补码表示形式而没有任何陷阱,因此在您的情况下,实现定义的转换是将位模式
解释为负值的二进制补码规范。您可以通过0xffffffef-232来计算哪个值,因为我们在这里谈论的是32位表示形式。或者,由于这只是一个8位的值,已被符号扩展为32位,因此您也可以将其计算为0xef-28,其中0xef是字符代码点。 干杯,……
联课
布埃郝卞簿
担每棱绰
缉康怪