我可以在临时结果中溢出uint32_t吗?

jps*_*alm 6 c

基本上当我这样做时,32位系统会发生什么:

uint32_t test (void)
{
  uint32_t myInt;

  myInt = ((0xFFFFFFFF * 0xFFFFFFFF) % 256u );

  return myInt;
}
Run Code Online (Sandbox Code Playgroud)

Die*_*Epp 11

我们假设这int是32位.

  1. 0xFFFFFFFF会有类型unsigned int.有一些特殊的规则可以解释这一点,但因为它是一个十六进制常量并且它不适合int,但确实适合unsigned int,它最终会成为unsigned int.

  2. 0xFFFFFFFF * 0xFFFFFFFF将首先进行通常的算术转换,但由于双方都unsigned int没有,所以没有任何反应.乘法的结果0xfffffffe00000001unsigned int通过使用模2 32值减少到的结果,导致值1与类型unsigned int.

  3. (unsigned int)1 % 256u等于1并且有类型unsigned int.通常的算术转换也适用于此,但同样,两个操作数都unsigned int没有发生.

  4. 结果转换为uint32_t,但它已经unsigned int具有相同的范围.

但是,我们假设它int是64位.

  1. 0xFFFFFFFF会有类型int.

  2. 0xFFFFFFFF * 0xFFFFFFFF会溢出!这是未定义的行为.在这一点上,我们不再试图弄清楚程序的作用,因为它可以做任何事情.也许编译器决定不为这个函数发出代码,或者同样荒谬的东西.

这将发生在所谓的"ILP64"或"SILP64"架构中.这些架构很少见,但确实存在.我们可以通过使用来避免这些可移植性问题0xFFFFFFFFu.