不从具有非void返回类型的函数返回值

时间:2013-05-08 13:14:05

标签: java c++ function return return-value

我读了here on SO如何:

在C ++中:

  1. 未从非空函数返回是未定义的行为。
  2. ... analysis requires inspection of the entire program, which is incompatible with separate compilation, and which is not even possible in the general case ...
  3. 根据我在该页面上的几个答案所做的,有时难以检查函数中是否存在return语句。那不是从非void函数返回的是C ++标准的未定义行为。

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

    Q值。我的理解是否正确? Java如何实现同样的目标?


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

    1. 如果在C ++标准中针对与Compiler相关的实现困难未定义,Java如何能够实现相同的目标。

    2. 如果不难做到,那么C ++标准是否应该将其定义为错误?

5 个答案:

答案 0 :(得分:3)

Java通过拒绝运行某些程序来做到这一点,即使它们总是返回一个值。采取以下(愚蠢)方法

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

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

总而言之:Java会拒绝你的方法,如果编译器无法证明它总会返回一个值。这有时会拒绝总是返回值的方法。

C ++只要信任程序员总是返回一个值,然后如果程序员没有返回某些内容就会在运行时爆炸。

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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

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

很明显,你永远不能脱离function()的结尾, 但是Java无论如何都需要一个return语句。

然而,语言有很大差异 激发了C ++不需要return语句的事实。 Java有一组非常有限的值对象(例如intdouble),所有这些都有轻松构建的值(例如00.0);其他一切都是一个指针(它会接受 null)。所以你总是有一些简单的回归 你知道它无关紧要的情况。在C ++中,用户定义 类型可以(通常也有)具有值语义,并且经常, 没有默认构造函数,或者您可以轻松实现的任何其他内容 构造。想象一下,必须提供一份退货声明 function()如果MyType的唯一非复制构造函数 需要两个或三个参数,所有这些参数都没有 也有价值构造者。所有Java都需要的地方 将是return null;

答案 3 :(得分: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;
  }
}

答案 4 :(得分:0)

Java编译器只需要遵循Java Language Specification所说的内容:

  

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

     

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

     

1.中断(§14.15),继续(§14.16)和返回(§14.17)语句导致控制权转移,可能妨碍正常完成包含它们的语句。

     

2.对某些表达式的评估可能会抛出Java虚拟机中的异常(第15.6节)。显式throw(第14.18节)语句也会导致异常。异常导致控制权转移,可能妨碍正常完成陈述。

     

...

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