![](/img/trans.png)
[英]C++ Warning C4244 'return': conversion from 'double' to 'int', possible loss of data Visual Studio 2015
[英]Visual C++ 6.0 - Possible Conversion Loss of Data (Warning C4244)
我正在使用一个相当旧的编译器,并且我相信编译器在其警告诊断中犯了一些错误。
typedef unsigned char uint8_t; // 8-bit byte
typedef unsigned int uint32_t; // 32-bit word (change to "long" for 16-bit machines)
typedef struct _sha256_ctx_t
{
uint8_t data[64];
uint32_t data_len;
unsigned __int64 bit_len; // unsigned long long
uint32_t state[8];
} sha256_ctx_t;
void crypto_sha256_final(sha256_ctx_t *ctx, uint8_t *digest)
{
uint32_t i;
i = ctx->data_len;
// Append to the padding the total message's length in bits and transform.
ctx->bit_len += ctx->data_len * 8;
ctx->data[63] = ctx->bit_len; // LINE 156 IS HERE!
ctx->data[62] = ctx->bit_len >> 8;
ctx->data[61] = ctx->bit_len >> 16;
ctx->data[60] = ctx->bit_len >> 24;
ctx->data[59] = ctx->bit_len >> 32;
ctx->data[58] = ctx->bit_len >> 40;
ctx->data[57] = ctx->bit_len >> 48;
ctx->data[56] = ctx->bit_len >> 56; // LINE 163 IS HERE!
local_sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output digest.
for (i = 0; i < 4; ++i) {
digest[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
digest[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
digest[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
digest[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
digest[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
digest[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
digest[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
digest[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
}
}
该代码导致此错误(从第 156 行到第 163 行):
SHA256.cpp(156):警告 C4244:“=”:从“无符号 __int64”转换为“无符号字符”,可能丢失数据
我猜这个旧编译器没有意识到用 0xFF 添加它会将结果缩小到一个字节。 有没有人有关于如何绕过错误警告的建议?
原始代码来源: https ://programmer.group/61737ba233df9.html
在这种情况下编译器没有问题
ctx->data[63] = ctx->bit_len; // LINE 156 IS HERE!
ctx->data[62] = ctx->bit_len >> 8;
ctx->data[61] = ctx->bit_len >> 16;
ctx->data[60] = ctx->bit_len >> 24;
ctx->data[59] = ctx->bit_len >> 32;
ctx->data[58] = ctx->bit_len >> 40;
ctx->data[57] = ctx->bit_len >> 48;
ctx->data[56] = ctx->bit_len >> 56; // LINE 163 IS HERE!
ctx->bit_len
是 64 位类型,因此显然将其存储到uint8_t
中是行不通的。 在 digest[i] = ( 0xFF
digest[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
. 唯一缺乏分析的情况是ctx->data[56] = ctx->bit_len >> 56
因为结果适合uint8_t
。 要获得 LSB,您需要进行显式转换,以便编译器知道您在做什么
ctx->data[62] = uint8_t(ctx->bit_len >> 8);
也就是说,不需要像那样手动复制,只需使用memcpy
和ntohll
。 代码不好,使用古老的编译器更糟。 现在有很多很好的加密库使用适当的 SIMD 和多线程,如 OpenSSL
编译器可以足够聪明地检查算术表达式的可能范围(在明显的情况下),如果它没有检查,这个编译器发出警告是非常正确的。 更新版本的编译器确实对此进行了不同的处理。
试试这个治疗方法:将分配的表达式转换为char
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.