即使我投出了每一个正确的操作数unsigned long long,警告仍然存在.不应该uint8_t << uint64_t有这样的隐式演员:(uint64_t) uint8_t << uint64_t?
这个答案表明我可以提升任何一个操作数,并且整个表达式都会被强制转换unsigned 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;
}
Run Code Online (Sandbox Code Playgroud)
不应该
uint8_t << uint64_t有这样的隐式演员:(uint64_t) uint8_t << uint64_t?
TL; DR - 不,移位运营商很特别.
完整答案
您正在描述的行为(基本上是匹配的操作数类型)被称为C标准中通常的算术转换.1
我们看到标准要求许多运营商(例如添加剂运营商):
[6.5.6]如果两个操作数都具有算术类型,则对它们执行通常的算术转换.
但是,我们在按位移位运算符的等效部分中看不到这样的短语.我们最接近的是:
[6.5.7]对每个操作数执行整数提升.结果的类型是提升的左操作数的类型.
但是,整数促销是一个不同的东西 - 他们(基本上)说任何小于的类型[unsigned] int转换为[unsigned] int.
所以编译器在这里警告是正确的.(并且我确信你可以猜到,解决方案是在左侧操作数上执行显式转换;)
1.为了这个答案的目的,我正在考虑C11(特别是N1570)规范.这种行为至少可以追溯到C99.
| 归档时间: |
|
| 查看次数: |
714 次 |
| 最近记录: |