非 void 方法编译中缺少 return 语句

2022-08-31 06:29:36

我遇到了一种情况,即非 void 方法缺少 return 语句,代码仍在编译。我知道 while 循环之后的语句是无法访问的(死代码),永远不会被执行。但是为什么编译器甚至没有警告返回某些内容呢?或者为什么一种语言会允许我们有一个非空洞的方法,它有一个无限循环而不返回任何东西?

public int doNotReturnAnything() {
    while(true) {
        //do something
    }
    //no return statement
}

如果我在 while 循环中添加一个 break 语句(甚至是条件语句),编译器会抱怨臭名昭著的错误:在 Eclipse 和 Visual Studio 中。Method does not return a valueNot all code paths return a value

public int doNotReturnAnything() {
    while(true) {
        if(mustReturn) break;
        //do something
    }
    //no return statement
}

Java和C#都是如此。


答案 1

为什么一种语言会允许我们有一个非void方法,它有一个无限循环并且不返回任何东西?

非 void 方法的规则是,返回的每个代码路径都必须返回一个值,并且该规则在程序中得到满足:返回的零代码路径中的零个返回一个值。规则不是“每个非 void 方法都必须有一个返回的代码路径”。

这使您能够编写存根方法,例如:

IEnumerator IEnumerable.GetEnumerator() 
{ 
    throw new NotImplementedException(); 
}

这是一种非无效的方法。它必须是一个非空洞的方法才能满足接口。但是,将此实现定为非法似乎是愚蠢的,因为它不会返回任何内容。

你的方法有一个无法到达的终点,因为一个(记住,a只是一个更愉快的写作方式)而不是一个(这是另一种形式)是无关紧要的。gotowhile(true)gotothrowgoto

为什么编译器甚至不警告返回某些内容?

因为编译器没有充分的证据证明代码是错误的。有人写了,似乎做这件事的人很可能知道他们在做什么。while(true)

在哪里可以阅读有关 C# 中可达性分析的详细信息?

请参阅我关于该主题的文章,请点击此处:

ATBG:事实上和法律上的可达性

您还可以考虑阅读 C# 规范。


答案 2

Java编译器足够聪明,可以找到无法访问的代码(循环后的代码)while

并且由于它无法访问,因此在那里添加语句(在结束之后)是没有意义的returnwhile

有条件的也是如此if

public int get() {
   if(someBoolean) {   
     return 10;
   }
   else {
     return 5;
   }
   // there is no need of say, return 11 here;
}

由于布尔条件只能计算为 or 或 ,因此无需显式提供 之后的代码,因为该代码无法访问,并且 Java 不会抱怨它。someBooleantruefalsereturnif-else