为什么glibc的__random_r分配了立即被覆盖的变量?

时间:2018-11-11 09:17:55

标签: c random glibc

我一直在寻找glibc的rand()函数的来源,an answer here links to

在链接之后,我对__random_r() TYPE_0 branch的代码感到困惑:

int32_t val = state[0];
val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
state[0] = val;
*result = val;

val变量被赋值然后立即被覆盖的意义是什么?保持状态的random_data结构是nothing unusual

正如人们所期望的那样,如果只删除-O2,则在godbolt上使用val进行编译会得到相同的代码。有这种模式的已知原因吗?


更新:这似乎是该答案I've updated the links there to the 2.28 version所链接的版本中的一个异常。通过使state[0]的内容更易于在本地监视列表中查看,可能是暂时进行的调试操作。

1 个答案:

答案 0 :(得分:1)

哇,那确实是一些令人难以置信的垃圾代码。

没有任何理由。

不仅不需要初始化val,而且事实是state[0]int32_t,并且与1103515245相乘在具有32位int(基本上是每个)的任何平台上,在GCC中触发不确定的行为(整数溢出)。 GCC是最常用于编译Glibc的编译器。


HostileFork所述,最新的2.28版本中的代码为:

int32_t val = ((state[0] * 1103515245U) + 12345U) & 0x7fffffff;
state[0] = val;
*result = val;

这样,不仅删除了无用的初始化,而且后缀U使无符号整数发生乘法运算,从而避免了不确定的行为。 & 0x7fffffff确保结果值适合int32_t并且为正。