不返回值,来自具有非void返回类型的函数

Not returning values, from a function with non-void return type

本文关键字:void 返回类型 函数 返回值      更新时间:2023-10-16

我在这里阅读了SO how:

在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 ...

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

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

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


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

  1. 如果在C++标准中由于编译器的实现困难而没有定义它,那么Java是如何实现的呢。

  2. 如果这不是很难做到的话,C++标准难道不应该把它定义为一个错误吗?

Java拒绝运行某些程序,即使它们总是返回一个值。采取以下(愚蠢的(方法

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

该方法总是返回true,但是java仍然拒绝接受它的有效性。C++中的相同方法是合法的,因为它总是返回一个值。

综上所述:如果编译器不能证明它总是会返回一个值,Java就会拒绝你的方法。这有时会拒绝总是返回值的方法。

C++只要相信程序员总是会返回一个值,然后在运行时如果程序员未能返回某个值,就会崩溃。

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

正如评论者所指出的,相反的情况是并非总是正确的。编译器可能会错误地发出警告,因为它无法正确地"理解"代码。

Java可能需要您编写永远无法访问的代码。比如:

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

很明显,你永远不会从CCD_ 3的末端掉下来,但是Java无论如何都需要一个return语句。

然而,这两种语言有一个主要的区别激发了C++不需要return语句的事实。Java有一组非常有限的值对象(例如intdouble(,所有这些都具有容易构造的值(例如00.0(;其他的都是一个指针(可以接受null(。所以你总是有一些简单的东西可以在情况下,你知道它是无关紧要的。在C++中,用户定义类型可以(并且通常确实(具有值语义,没有默认构造函数,也没有任何其他可以轻松使用的构造函数建筑想象一下,必须为function()如果是MyType的唯一非复制构造函数需要两到三个参数,所有这些参数的类型都没有也有值构造函数。所有Java都需要将是CCD_ 11。

是的,你的理解是正确的。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;
  }
}

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

(8.4.7(如果一个方法被声明为具有返回类型,那么如果该方法的主体能够正常完成,则会发生编译时错误(§14.1(

(14.1(但是,某些事件可能会阻止报表正常完成:

1.中断(§14.15(、继续(§14.16(和返回(§14.17(声明导致控制权转移,可能会阻止包含这些声明的声明的正常完成。

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

关于正常完成的更多细节在JLS中进行了定义,尤其是§14。