无限循环:int与float

Smi*_*ory 6 c floating-point loops

我正在完成一项家庭作业,我可能会对这件事感到兴奋,所以我只是在寻求一些意见.这是基本代码:

for(x = 100; x > 0; x = x + x) {
    sum = sum + x;
Run Code Online (Sandbox Code Playgroud)

有两个版本:一个x是a float,一个是int.问题是这些无限循环.

我在想,当它x是一个时int,它最终会溢出,使它小于零并且循环将停止.当xa是a时float,x将达到无穷大并且循环将是无限的.

我接近了吗?

sep*_*p2k 8

有符号整数增加超出其限制时的行为是未定义的.所以循环可能结束或者可能是无限的.或者它可能会崩溃(或循环可能永远不会运行).或者正如一些C大师所说,恶魔可能会飞出你的鼻子 - 虽然我个人怀疑任何编译器实现者都会遇到实现鼻子恶魔功能的麻烦.

就浮点值而言,你是正确的,它将是一个无限循环.

  • 这是在3.4.3中首次定义未定义行为的未定义行为的第一个示例. (6认同)

Bli*_*ndy 2

你确实是对的,整数将溢出到负值(只要它们有符号),因此循环将结束,浮点数将坚持“+无穷大”,它总是大于除 之外的任何数字NaN

编辑:我纠正了,该int版本确实无限循环(由于某些编译器的假设): http: //ideone.com/HZkht

  • “整数将溢出为负值”这不是保证的行为。 (4认同)
  • 现代编译器会将整数循环优化为无限循环。 (4认同)
  • @Blindy:只有当“x + Positive_integer”大于 MAX_INT 时,它才是未定义的,编译器无法知道这一点。关键是你可能会做类似“f(x,y) { if(x > y) {foo} else {bar} }”的事情,然后将其称为“f(x, x+1)”。现在,如果编译器内联它,它最终会得到 `if(x > x+1) {foo} else {bar}`,然后它可以优化为 `bar`。在大多数情况下(不涉及溢出),这是一个完全有效的优化,并且不会违背程序员的期望。 (3认同)
  • 顺便说一句:本文的“有符号整数溢出”部分在这里似乎相关:[每个 C 程序员应该了解未定义行为](http://blog.llvm.org/2011/05/what-every-c-programmer-应该知道.html) (2认同)
  • 嗯,这绝对很奇怪(至少在我看来),GCC4 确实将第一个优化为无限循环。我今天学了些新东西! (2认同)
  • @Blindy:并不总是人们编写代码。例如,当编译器内联代码时,它通常会得到在给定上下文中基本为真(或假)的条件。优化这些是一个很好的优化领域(通常允许您进一步优化功能)。如果禁止编译器假设“x + Positive_integer > x”,则会失去很多优化潜力。 (2认同)
  • @Blindy:我什么时候会写“if(x,y) {foo} else {bar}”?案例很多。我想到了“gcd”函数。诚然,我通常不会调用 `gcd(x,x+1)`,但在很多情况下,我会在编译器知道 `x` 中的哪一个的情况下调用 `gcd(x,y)`并且“y”更大。 (2认同)