为什么glibc的__random_r分配变量会立即覆盖?
我正在寻找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. 正如人们所预料的那样,如果你只消除val,那么在godbolt上使用-O2进行编译会得到相同的代码.这种模式有一个众所周知的原因吗? 更新:这似乎是与该答案相关联的版本中的一个异常,I’ve updated the links there to the 2.28 version.可能是暂时通过使状态[0]的内容更容易在本地监视列表中看到来帮助调试的东西? 解决方法
哇,这确实是一些难以置信的垃圾代码.
没有理由这样做. 并且不仅需要val的初始化,事实是state [0]是一个int32_t,乘以1103515245将在任何具有32位整数的平台上触发GCC(整数溢出)中的未定义行为(=基本上每一个) . GCC是最常用于编译Glibc的编译器. 如HostileFork所述,最近的2.28中的代码为: int32_t val = ((state[0] * 1103515245U) + 12345U) & 0x7fffffff; state[0] = val; *result = val; 这样,不仅删除了无用的初始化,而且U后缀使得无符号整数发生乘法,从而避免了未定义的行为. & 0x7fffffff确保结果值适合int32_t并且为正. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |