2

我在这里读到了阅读了如何:

在 C++ 中:

  1. 不从非 void 函数返回是未定义的行为。
  2. ... analysis requires inspection of the entire program, which is incompatible with separate compilation, and which is not even possible in the general case ...

从我在该页面上的几个答案中得出的结论,很难,有时甚至不可能检查函数中是否存在 return 语句。C++ 标准未定义非 void 函数返回的行为。

但是,我听说在Java中,同样的事情在编译时被报告为错误。

Q. 我的理解正确吗?Java 又是如何做到这一点的呢?


编辑:为了清楚起见,我有兴趣了解:

  1. 如果在 C++ 标准中未定义 Compiler 相关的实现困难,Java 是如何实现的。

  2. 如果这不难做到,C++ 标准不应该将其定义为错误吗?

4

5 回答 5

3

Java does it by refusing to run some programs, even if they always return a value. Take the following (stupid) method

public boolean test() { 
   boolean var=true;
   if(var)
      return true;
}

The method always return true, but java will still refuse to accept it as valid. The same method in C++ would be legal because it always return a value.

So to sum up: Java will refuse your method, if the compiler can't prove that it always will return a value. This will sometimes reject methods which always does return a value.

C++ Just trust the programmer always to return a value, and then blows up at runtime if the programmer failed to return something.

于 2013-05-08T13:19:00.970 回答
2

如果存在不是return来自非 void 函数的代码路径,我所知道的所有 C++ 编译器都会报告错误或警告。

正如评论者指出的那样,情况并非总是如此。编译器可能会发出错误警告,因为它无法正确“理解”代码。

于 2013-05-08T13:17:10.747 回答
2

Java 可能要求您编写永远无法达到的代码。考虑类似的事情:

void neverReturns() { throw SomeException(); }
MyType function()   { neverReturns();        }

很明显,您永远不能脱离function().

然而,这两种语言之间存在重大差异,这促使 C++ 不需要 return 语句这一事实。Java 有一组非常有限的值对象(例如intor double),所有这些对象都具有易于构造的值(例如0 or 0.0);其他一切都是一个指针(它将接受 null)。因此,在您知道它无关紧要的情况下,您总是可以返回一些简单的东西。在 C++ 中,用户定义的类型可以(并且通常确实)具有值语义,并且通常没有默认构造函数,或者任何您可以轻松构造的东西。想象一下,必须为 function()if 的唯一非复制构造函数提供 return 语句MyType 需要两个或三个参数,它们都是没有值构造函数的类型。所有 Java 都需要的地方是return null;.

于 2013-05-08T13:25:42.197 回答
1

是的,你的理解是正确的。java 这样做的方式是严格并发出错误,即使对于总是返回值的方法也是如此。

假设您有以下方法。我们知道它总是会返回一个值,因为涵盖了所有情况:a 要么大于零,要么小于或等于零。但是 java 不知道这一点,它看到一个带有返回的“if”,一个带有返回但没有“else”的“else if”,因此没有返回,因此会报告错误。

int foo( int a ) {
  if ( a > 0 ) {
    return -1;
  }
  else if ( a <= 0 ) {
    return 1;
  }
}

修复java代码需要从else中删除if

int foo( int a ) {
  if ( a > 0 ) {
    return -1;
  }
  else /*if ( a <= 0 )*/ {
    return 1;
  }
}
于 2013-05-08T13:33:44.587 回答
0

Java 编译器只需要遵循Java 语言规范所说的:

(8.4.7) 如果方法被声明为具有返回类型,则如果方法的主体可以正常完成,则会发生编译时错误(第 14.1 节)。

(14.1) 但是,某些事件可能会阻止语句正常完成:

1.break (§14.15)、continue (§14.16) 和 return (§14.17) 语句会导致控制权转移,这可能会阻止包含它们的语句的正常完成。

2. 某些表达式的求值可能会从 Java 虚拟机中抛出异常(第 15.6 节)。显式 throw (§14.18) 语句也会导致异常。异常会导致控制转移,这可能会阻止语句的正常完成。

……

JLS 中定义了有关完整正常情况的更多详细信息,尤其是第 14 节。

于 2013-05-08T13:25:15.133 回答