为什么“控制到达非void函数的末尾”只是一个警告?这合法吗?

5
定义一个返回类型为非void的函数,在函数结尾没有return语句,这样做是否合法? gccclang只会发出警告。这样的代码是否合法?还是说这些编译器只是宽容? gcc

warning: no return statement in function returning non-void [-Wreturn-type]

clang

warning: control reaches end of non-void function [-Wreturn-type]

如果这是合法的,那么有没有定义行为来确定将返回什么值?

任何编译器都应将其提升为错误的警告之一。 - Bathsheba
它至少有一个用途。这个问题的灵感来自于这个问题的答案。http://stackoverflow.com/questions/27011345/generate-mangled-names-from-source-code?noredirect=1#comment42549548_27011345 - Praxeolitic
2个回答

5

正如 Bathsheba 已经说过的那样,非 void 函数的末尾流出是未定义行为。这是一个警告而不是错误的原因是您可能能够证明这永远不会发生。例如,请考虑以下内容:

// My magic function.
// It is forbidden to call it with values between -5 and 5
bool fun (int i) {
    if (i >= 5)
        return true;
    if (i <= -5)
        return false;
}

现在,只要函数的用户仔细阅读注释,就可以定义良好的行为。显然,这是一件危险的事情,所以编译器警告您不要这样做。
编辑:正如MSalters所提到的,对于私有成员函数来说,这种情况较少危险,因为类不变式可以保证该函数永远不会被错误使用。考虑以下示例:
// Every member function of SomeClass makes sure 
// that i_ is in the legal range when it's done
class SomeClass {
    public:
        SomeClass () : i_{27} {}
    // Possibly more public or private functions that all make sure i_ stays valid
    private:
        bool foo () {if (i_ > 3) return true;}
        int i_;
};

现在,您(作为类维护者)可以确保i_始终至少为4,并且foo将始终正常工作。个人而言,我仍然会避免这样做,因为它会影响可维护性和可读性,但是这比自由版本要好,因为现在"只有"所有类维护者需要关注此不变量/可能出错。


1
当函数是私有类成员时,它当然会稍微安全一些。这些函数可以依赖于类不变量。 - MSalters
@MSalters,您能解释一下为什么这样做更安全吗? - Neil Kirk
@NeilKirk 在编辑中完成。 - Baum mit Augen
为什么不使用断言,这样你就总是有保障了。 - Neil Kirk
1
@NeilKirk 如果在编译期间未定义 NDEBUG,那么您就可以放心使用了。不过,为了确保安全,您可以抛出 std::invalid_argument 异常。 - Baum mit Augen
如果根据您程序的限制,这是不应该在发布版本中发生的事情。我知道这是一个理想的情况。 - Neil Kirk

4

根据C++标准6.6.3:

函数末尾的流程与没有返回值的返回语句相同;这会导致在有返回值的函数中出现未定义行为。

因此,没有明确的返回值是一种未定义行为


读取返回值的内容是否导致 UDB,函数调用是 UDB 还是函数定义是 UDB? - Praxeolitic
标准似乎没有指定这一点。我想试图确定确切的位置是徒劳无功的,特别是对于内联函数来说。 - Bathsheba
如果一个程序具有UDB,则它就是全部 UDB,但我的意思是,如果一个程序仅定义但不调用该函数,那么它是否是UDB?没有读取返回值的情况呢?标准是否有规定? - Praxeolitic
2
只要程序控制未到达缺失“return”值的函数的闭合“}”,您就是安全的。 - Bathsheba
澄清一下:这意味着未定义行为可能仅在某些输入情况下发生。实际运行时的流程定义了UB,而不是编译时的潜在流程。然而,编译器可能假设所有无条件导致该闭合}的代码路径都是不可达的。它甚至可以假设导致UB的输入实际上在运行时不会发生,并基于此进行优化。 - MSalters
可能有助于链接到您引用的最接近的草案,以便其他人可以自行查看。 - Shafik Yaghmour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接