gcc 7.2:警告:左移位计数>=类型宽度

gcc 7.2:警告:左移位计数>=类型宽度,c,gcc,C,Gcc,即使我将每个右操作数强制转换为无符号long-long,警告仍然存在。不应该 这个答案表明我可以提升任意一个操作数,整个表达式将强制转换为无符号long-long,但这可能是错误的 bool dgBioReadU64LE(DgBioFile *file, uint64_t *x) { uint8_t u[8]; if (!dgBioReadU8v(file, LEN(u), u)) return false; *x = u[0]|(u[1]<<8ULL)|(u

即使我将每个右操作数强制转换为无符号long-long,警告仍然存在。不应该 这个答案表明我可以提升任意一个操作数,整个表达式将强制转换为无符号long-long,但这可能是错误的

bool dgBioReadU64LE(DgBioFile *file, uint64_t *x) {
    uint8_t u[8];
    if (!dgBioReadU8v(file, LEN(u), u)) return false;
    *x = u[0]|(u[1]<<8ULL)|(u[2]<<16ULL)|(u[3]<<24ULL)|(u[4]<<32ULL)|(u[5]<<40ULL)|(u[6]<<48ULL)|(u[7]<<56ULL);
    return true;
}

bool dgBioReadU64BE(DgBioFile *file, uint64_t *x) {
    uint8_t u[8];
    if (!dgBioReadU8v(file, LEN(u), u)) return false;
    *x = u[7]|(u[6]<<8ULL)|(u[5]<<16ULL)|(u[4]<<24ULL)|(u[3]<<32ULL)|(u[2]<<40ULL)|(u[1]<<48ULL)|(u[0]<<56ULL);
    return true;
}
是的

标准上说:

6.5.7位移位运算符 对每个操作数执行整数提升。结果的类型是升级的结果类型 左操作数。如果右操作数的值为负或为 大于或等于提升后的左操作数的宽度,则 行为是未定义的

这意味着您需要强制转换左边的操作数,强制转换右边的操作数不会改变任何东西


左移位运算符和右移位运算符的结果不应该与左操作数的类型相同吗。因此,右操作数的类型不会影响结果的类型


您需要将左操作数强制转换为无符号long-long以获得所需结果。

您链接的答案有误导性。这似乎表明您可以加宽其中一个操作数,它将触发另一个操作数到通用加宽类型的自动转换。对于C语言中的大多数二进制运算符都是这样。然而,对于移位运算符则不是这样

在这方面,C中的移位运算符实际上是特殊的。他们的行为不对称。将右操作数的类型更改为更宽的类型不会触发将左操作数转换为右操作数的类型,也不会影响结果类型。结果类型始终由左操作数的可能提升类型定义

在本例中,您特别需要将左操作数转换为无符号长类型

即使我将每个右操作数强制转换为无符号long-long
警告依然存在。当@antti-因为我不知道的时候,你为什么要使用n1548;。下一步在键盘上时,我将更新答案。