'包装'乘法溢出的结果是什么?

9 c integer-overflow

这里的bcache源包含以下行:

schedule_delayed_work(&dc->writeback_rate_update,
    dc->writeback_rate_update_seconds * HZ);
Run Code Online (Sandbox Code Playgroud)

writeback_rate_update_seconds被定义为unsigned int,在x86_64上似乎是32位,我不确定是什么类型HZ,但我相信该值为1000并假设它是32位或更少.

如果我设置writeback_rate_update_seconds为2147483647,实际传递给什么值schedule_delayed_work?第二个参数schedule_delayed_work似乎是a long,但这并不意味着操作数在乘法溢出之前被提升为long,是吗?

Phi*_*hil 2

鉴于:

#include <stdio.h>
#include <stdlib.h>

int schedule_delayed_work( unsigned long param )
{
    printf("value: %lu\n", param);
    return 0;
}

int main(int argc, char **argv)
{
    unsigned int writeback_rate_update_seconds;
    unsigned int HZ;
    writeback_rate_update_seconds = 2147483647;
    HZ = 1000;
    schedule_delayed_work( writeback_rate_update_seconds * HZ );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您将被4294966296传递到该函数。

如果将函数调用更改为强制转换:

schedule_delayed_work( (unsigned long) writeback_rate_update_seconds * HZ );
Run Code Online (Sandbox Code Playgroud)

...您将被2147483647000传递到该函数。

我没有查看 C 标准来了解标准行为是什么,但这已经过测试:

Apple LLVM version 8.1.0 (clang-802.0.38)
Target: x86_64-apple-darwin16.7.0
Run Code Online (Sandbox Code Playgroud)