【问题标题】:How compilers evaluate mathematical expressions?编译器如何评估数学表达式?
【发布时间】:2011-12-29 08:49:41
【问题描述】:

我正在阅读this 问题,然后我做了以下内容。

a = b + (c - (b = c)) + (a - (c = a))

我在 C 和 Java 中尝试过。它适用于 java ,但不适用于 C。

当然,这取决于编译器如何评估这些表达式,在谷歌搜索之后,我没有找到答案。

【问题讨论】:

  • 编译器不会评估这些表达式(好吧,如果它们是常量,它可能,但它一定不会产生影响)。它只是用另一种语言生成大致等效的代码(javac 的情况下为 JVM 字节码,gcc 的情况下为您的处理器的机器代码,cl.exe 等)。

标签: java c compiler-construction


【解决方案1】:

它在 C 中不起作用的原因是因为 C 没有准确指定 c = a 何时发生。它可以出现在该语句中引用的另外两次之前或之后。

所以根据编译器决定何时执行赋值c = a,表达式的值会有所不同。它没有定义。

即如果在c = a 之前评估b = c,则b 将采用c 的原始值。如果之后进行求值,则取值为a。

【讨论】:

  • 更糟糕的是,由于这是未定义的,任何事情都可能发生。例如读取既不是旧值也不是新值的东西。 (这对于 32 位机器上的 64 位值是可以理解的,其中写入新值需要两条指令)
  • 关于 32 位的 64 位值,这是一个很好的观点。我从来没有想过。 (当然,我更愿意从一开始就避免未定义的行为,而不是试图推断会发生什么。)
  • @Mystical,我同意避免使用 UB,但我发现如果我理解为什么一个实现可能会表现得很奇怪,那么记住它是 UB 而不是简单地未指定更容易。
【解决方案2】:

您可以参考 java expressions document 以获得完美答案。

【讨论】:

  • 那只能指定它在 Java 中的工作方式。它无法解释为什么它在 C 中的工作方式不同。
猜你喜欢
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
相关资源
最近更新 更多