C 将要存储在int中的左移短字符是否未定义?

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

我正在读一本书,它实现了一个自己动手的DNS消息阅读器,它试图查看某个特定字段是否设置为true。 这本书使用的一段代码我不太懂

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
    是有符号的还是无符号的

  • int
    16位或更宽

    (msg[10] << 8) + msg[11];
    

    请不要描述
    msg
    的类型,而是显示声明。在移位完成之前,操作数被转换为
    int
    ,因此
    10010001
    被转换为
    00000000000000000000010010001
    (或
    11111111111111111111110010001
    ),并且只有在移位完成之后才执行左移位。请参见:“对两个操作数执行整数升级。“@pmg我无法理解升级是否自动完成,此操作何时会导致UB。您的计算机中的纯
    char
    是有符号类型还是无符号类型?重要的是如果字符总是转换为int,那么使用无符号字符或有符号字符有什么意义?它提供了什么保护?@Khaled Gaber当
    char
    值为负值时,左移为UB。对于
    unsigned char
    ,提升为
    int
    的值不是负值。只要左移位在
    int
    符号位中不移位,一切都好。@是的,现在我没有注意到符号是数字的最高有效位:)。@KhaledGaber“整数提升在每个操作数上执行。”并不意味着参数提升为
    int
    。它也可以升级为
    unsigned int
    或更大的所需签名类型。请看一下“整数提升”主题以了解其含义。@vlad_tepesch详细信息:在移位运算符的情况下,如果操作数的宽度小于
    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];