【问题标题】:Is infinite loop is considered "run time error"? (c)无限循环是否被认为是“运行时错误”? (C)
【发布时间】:2021-03-30 20:03:15
【问题描述】:

我有一个问题:


#include <stdio.h>
int main()
{

    float s;

    for (s = 100000001.0f; s <= 100000010.0f; s += 1.0f) {
    };

    printf("SLABC\n");
 
return 0;

} 

它是无限循环,因为浮动的东西。但是,如果这被认为是“运行时错误”或“什么都不打印”,那我不知道

【问题讨论】:

  • “运行时错误”通常意味着“崩溃”。这不会崩溃。
  • 这里的假设是float 不能超过一个特定的值,比如16777216.0

标签: c


【解决方案1】:

我假设您使用的是 C11 之前的版本,因为大学最常教授旧版本。如果没有,请查看 M.M 的答案。

不管怎样,我们可以看看所有的答案:

  1. 不编译:这是错误的。该程序完美编译。然而,它可能会给出一个警告,这与一个错误不同。
  2. 导致运行时错误:否。这段代码一直在运行。它将永远保留在for 循环内,甚至更久(或者只是关闭程序,不要太戏剧化)。第 3 点也是如此。
  3. 打印 SLABC:没有。它位于for 循环内。阅读第 2 点了解更多信息。
  4. 什么都不打印:这是正确的答案。没有错误,程序将执行所有内容。

您的程序本质上就像我的列表。如果你正确地遵循它,你将被困在第 2 点和第 3 点之间,永远无法阅读第 4 点。但你比这更聪明。

【讨论】:

  • 一个很好笑的答案。如果可以的话,我会投票两次
  • @BasileStarynkevitch 虽然自 C11 以来不正确
  • @M.M 自 C11 以来确实不正确,但我假设他是一名大学生。他们仍然在大多数大学教授早期版本。你的回答确实比我的解释得更好。但是 OP 对 C 来说可能是新手,所以我尽量让它有点易于理解。
  • 也许最好在答案中添加“C11 之前”,因为现代编译器可以执行上述任何操作。最新的clang以错误状态退出进程,godbolt-gcc给出运行时错误。
  • @M.M 我在回答中添加了对您回答的参考。
【解决方案2】:

由于线程被添加到 C 中(即 C11 标准),因此存在向前进度保证。每个循环都必须做某事或退出,“有意的”无限循环有一个例外,例如while(1)

来自 C11 6.8.5/6 的文本:

控制表达式不是常量表达式的迭代语句,不执行输入/输出操作,不访问 volatile 对象,并且在其主体、控制表达式或(在for 语句)它的表达式-3,可能被实现假定为 终止。

您的程序属于这种情况,因为循环条件不是常量表达式,因为它涉及变量s

因此程序可能表现得好像循环终止了,即它可以继续打印SLABC 并退出。或者(当然取决于您的实现中float 的属性)它可能永远停留在循环中并且什么也不输出。

此子句的目的是允许优化器删除空循环,而不必证明循环最终会结束。或者换句话说,runtime complexity is not considered part of the program's observable behaviour,除非永远挂起是由 while(1) 或类似的信号故意发出的。

注意: 可以说,尝试执行这样的循环意味着行为是未定义的,因为标准没有说明循环在此终止意味着什么方式(例如,循环后s 可能保留哪些值?)。如果接受此参数,则可能出现任何其他结果,包括编译错误。

clang (trunk) 似乎确实将其视为未定义的行为,当执行到达循环时中止程序。 godbolt link。 gcc-10.2 的 godbolt 实现也会在经过一段时间后导致运行时错误(这不是不合格的,因为可能会假定循环终止)。

【讨论】:

    【解决方案3】:

    我尝试在在线 c 编译器上运行这个程序

    #include <stdio.h>
    int main(){
        for(int i = 0; i < 100000000; i++){
            char a = 0;
            printf("%d",i);
        }
        return 0;
    }
    

    输出:

    ...Program has been killed (because output is larger than 20 MB) 
    

    执行一段时间后,程序会自动终止。这取决于编译器的内存大小。

    Prints Nothing 
    

    是你的答案。

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      • 2012-02-28
      • 2019-10-16
      • 1970-01-01
      • 2014-02-25
      • 2020-05-19
      • 1970-01-01
      相关资源
      最近更新 更多