C 将要存储在int中的左移短字符是否未定义?
我正在读一本书,它实现了一个自己动手的DNS消息阅读器,它试图查看某个特定字段是否设置为true。 这本书使用的一段代码我不太懂C 将要存储在int中的左移短字符是否未定义?,c,dns,undefined-behavior,bit-shift,C,Dns,Undefined Behavior,Bit Shift,我正在读一本书,它实现了一个自己动手的DNS消息阅读器,它试图查看某个特定字段是否设置为true。 这本书使用的一段代码我不太懂 const int qdcount = (msg[10] << 8) + msg[11]; const int qdcount=(msg[10]chartype(即8位) qdcount==>应该是一个16位的字段,包含大量DNS查询(由两个字段组成msg[10]和msg[11]) 那么,这个代码是如何工作的(例如,如果msg[10]=01001 000
const int qdcount = (msg[10] << 8) + msg[11];
const int qdcount=(msg[10]char
type(即8位)
qdcount
==>应该是一个16位的字段,包含大量DNS查询(由两个字段组成msg[10]
和msg[11]
)
那么,这个代码是如何工作的(例如,如果msg[10]=01001 0001),将其左移8应该得到(1000 0000)即UB,那么所做的任何计算都将导致错误的答案。假设msg[11]=0010 1111
。计算结果为1000 0000+0010 1111,对吗?那么这一行代码是如何准确工作的。来自链接的第6.5.7.4段版本
[…]E1 16
)。至少有两个独立的注意事项
是有符号的还是无符号的char
16位或更宽int
(msg[10] << 8) + msg[11];
请不要描述
的类型,而是显示声明。在移位完成之前,操作数被转换为msg
,因此int
被转换为10010001
(或00000000000000000000010010001
),并且只有在移位完成之后才执行左移位。请参见:“对两个操作数执行整数升级。“@pmg我无法理解升级是否自动完成,此操作何时会导致UB。您的计算机中的纯11111111111111111111110010001
是有符号类型还是无符号类型?重要的是如果字符总是转换为int,那么使用无符号字符或有符号字符有什么意义?它提供了什么保护?@Khaled Gaber当char
值为负值时,左移为UB。对于char
,提升为unsigned char
的值不是负值。只要左移位在int
符号位中不移位,一切都好。@是的,现在我没有注意到符号是数字的最高有效位:)。@KhaledGaber“整数提升在每个操作数上执行。”并不意味着参数提升为int
。它也可以升级为int
或更大的所需签名类型。请看一下“整数提升”主题以了解其含义。@vlad_tepesch详细信息:在移位运算符的情况下,如果操作数的宽度小于unsigned int
到int
或int
,则操作数会经历通常的整数提升,但不会扩展到更宽的类型。在无符号
的情况下,a移位b
的类型不影响b
的类型<代码>整数a
// char msg[100]; // const int qdcount = (msg[10] << 8) + msg[11]; char unsigned msg[100]; const unsigned qdcount = ((unsigned) msg[10] << 8) + msg[11];