【问题标题】:Infinite loop at compile time?编译时无限循环?
【发布时间】:2009-10-07 22:11:00
【问题描述】:

是否可以在编译时进入无限循环?

当我尝试编译时,我的程序似乎进入了一个无限循环。我有一个带有类构造函数的类,它调用方法 gameRun()。 gameRun() 在执行结束时调用自己,但应该有适当的检查才能在运行时中断它......但是当我尝试编译该类时,我实际上似乎得到了一个无限循环。

我对编译的理解是它实际上并没有执行代码......这意味着除非编译器的源代码中确实存在严重的错误,否则不可能进入无限循环。这是正确的吗?

我正在使用 Java 编写代码,并且正在使用 BlueJ(我正在从中成长的初学者 IDE)作为我的 IDE。

提前致谢。

.....................................

感谢大家提供这么多有用的回复。只是想我会发布一个更新,因为这似乎引起了一些兴趣,我自己也很好奇。

自从我发布原始错误以来,我没有对 BlueJ 或这个错误做很多事情,因为我已经从项目中获取了源文件,并且能够成功地使用 eclipse 编译和运行它们。这向我表明这是一个 BlueJ(或相关)问题。我继续使用 eclipse 进行这个项目,没有任何这种性质的问题。当我能够再次使用带有原始项目的机器时,我将跟进有关该问题的更多详细信息。 (从那以后什么都不应该改变)

.....................................

作为事后的想法...有什么方法可以将此问题链接到自发布以来我创建并注册的帐户?我找不到这样做的方法,它会使跟踪更方便...

【问题讨论】:

  • 注释掉这个电话有帮助吗?
  • 多个jstack/ctrl-`/ctrl-break`告诉你任何有用的东西。
  • 您能从新帐户编辑这个问题吗?如果没有,请在 MetaStackOverflow 询问。

标签: java infinite-loop compile-time


【解决方案1】:

某些语言确实允许编译器进入无限循环。 Java 不是这些语言之一。 :-)

【讨论】:

  • 我会试着弄清楚它在做什么,以及为什么。非常感谢。 =)
  • 只是出于兴趣,哪些语言可以,最简单的方法是什么?
  • 如果您使用模板元编程,C++ 可以让您做到这一点 - 它是图灵完备的,因此编写无限循环代码很简单。
  • @deworde:你可能会因为递归模板太深而导致 C++ 编译器失败……但不知道这算不算“无限循环”。
  • 如果您编写一个包含无限循环的注释处理器并将其添加到您的编译器类路径中,javac 也可能永远循环:)
【解决方案2】:

你是对的,编译器不执行代码,只会因为一个错误而进入一个无限循环。我相信 Sun 的 javac 编译器没有这样的错误。

我不知道 BlueJ 在“幕后”使用的是什么编译器,但是当 Ant 运行 javac 时,我发现了一个问题,这使得编译需要 真的 很长时间。简单地说,在某些情况下,Ant 会指示编译器加载给定目录下的每个 类。如果该目录包含数百个第三方库,则可能需要一段时间……甚至内存不足。

【讨论】:

  • BlueJ 允许您选择任何 JVM,它几乎总是 sun 的。
【解决方案3】:

如果您只使用 javac,您的编译是否会挂起(循环)?

我从未见过在编译 Java 时编译会无限期挂起,我想知道 BlueJ 是否有问题。

【讨论】:

  • 问题很可能出在 BlueJ 上。我只是在编译代码,但它似乎永远不会完成编译,并且会弹出一个窗口并显示“堆栈溢出”错误。系统试图跟踪的呼叫似乎太多了...... =/
  • 这听起来很可能是我。我相信这里的大多数“解决方案”都会导致堆栈溢出。不过,很高兴你能深入了解它....
【解决方案4】:

例如,如果要编译一个文件,编译器首先必须完成对该文件的编译,这在理论上是可行的。 (啊……递归)。 但我想检查这种疯狂将是现实世界的编译器会处理的第一件事。

但我认为它不会发生在方法/函数上,除非(假设)编译器试图将尾递归解析为更简单的实现,但失败了。但是,我再次无法想象现代 Java 编译器会出现问题,即使它根本存在。当然,我认为编译器最终会放弃并发布错误,而不是无限循环。

更可能是 IDE 而不是编译器。猜测一下,IDE 可能会尝试将警告/错误跟踪到代码中的源代码,以突出显示它并被困。 BlueJ 是否有关于编译器错误/警告的文本​​突出显示?您可以尝试将其关闭。

尽管正如许多其他人已经建议的那样,第一个真正的测试是使用从命令行编译

javac *.java

或者你的代码使用的任何文件。

编辑:抱歉,我没有回复你。为了将来参考,从命令行编译(我假设 Windows 作为你的操作系统):

  1. 通过转到开始菜单打开命令行并选择运行...
  2. 在“运行”对话框中键入 cmd,然后单击“确定”。
  3. 这应该会打开一个 cmd.exe 控制台。
  4. 从这里,使用“cd”命令将目录更改为包含您的 java 文件的目录。 (cd "我的文档\Java\Monster Battle\core")
  5. 进入正确的目录后,键入“javac *.java”。这将运行编译器而无需处理 IDE。它应该在编译时暂停,完成后,您会返回命令提示符。
  6. 如果您输入“javac *.java -verbose”,您将获得完整的输出,以防无限循环。

如果这工作正常,那就是 IDE 错误。向他们发送错误报告。如果没有,恭喜!您发现了一些非常有趣的东西,可能会让一些可怜的 Sun 开发人员困一个月。

【讨论】:

  • 我似乎记得它在一段时间后给出了堆栈溢出错误,但我认为它可能已经让编译器运行或其他什么,否则我不会认为它是一个无限循环...一旦我有能力,我会检查并看看它到底是什么。您是否有机会向我发送有关如何进行命令行交易(javac *.java)的更多详细信息?我对此并不熟悉,我并没有大量使用 Windows 命令行,因为过去我的大部分更重要的项目都是在 linux 机器上远程运行的,并且是 C++。 =s
【解决方案5】:

如果 BlueJ 确实使用自己的编译器,您可能已经在其中或围绕它的 BlueJ 构建工具中发现了一个错误。

您可能会对此采取BinaryChop 方法:将您的程序分成几部分,单独编译它们,看看是否可以将编译器挂起行为隔离到一个小的特定测试用例中。在一天结束时,您要么有一个出色的错误报告向 BlueJ 人员展示,要么您会发现您的程序确实可以编译(但您会摸不着头脑)。

【讨论】:

  • 我可能会尝试这个。与此同时,我在周末切换到 Eclipse 并在那里取得了重大进展。 (相同的代码在 Eclipse 中编译得很好,我从文件夹中获取相同的源文件开始)。如果我这样做,我只会尝试找出这是否是 BlueJ 错误,但考虑到 BlueJ 是作为 Java 初学者的入门者,我认为这并不特别重要,而且我可以'真的不能想象高中课程中的某个人(像这样设计的)运行这样的代码。
【解决方案6】:

AFAIK,标准 Java 不能无限编译。

您确定问题出在编译而不是 BlueJ 提供的其他功能上吗?许多基于 Eclipse 的 IDE 在重建期间执行多个操作,而编译只是其中之一。有可能是别的东西。

你到底看到了什么?一个无休止的 Eclipse 任务?

【讨论】:

  • 我收到“堆栈溢出”错误,它显示了我认为是 BlueJ 的某些类型的调用的大列表。我现在不在有程序的系统上,所以我无法给出确切的错误,但这不是我习惯用 BlueJ 看到的对初学者友好的错误消息。
【解决方案7】:

尽量使您正在编译的源代码尽可能小,并且仍然表现出您描述的行为。这样做的过程可能会帮助您确定问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 2014-12-23
    相关资源
    最近更新 更多