繁体   English   中英

Visual C++ 6.0 - 可能的数据转换丢失(警告 C4244)

[英]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);

也就是说,不需要像那样手动复制,只需使用memcpyntohll 代码不好,使用古老的编译器更糟。 现在有很多很好的加密库使用适当的 SIMD 和多线程,如 OpenSSL

编译器可以足够聪明地检查算术表达式的可能范围(在明显的情况下),如果它没有检查,这个编译器发出警告是非常正确的。 更新版本的编译器确实对此进行了不同的处理。

试试这个治疗方法:将分配的表达式转换为char

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM