C和C++函数没有return语句

eri*_*rip 9 c c++ return

在查看工作代码时,我发现了一些(看似)令人反感的代码,其中函数具有返回类型,但没有返回.我知道代码有效,但认为它只是编译器中的一个错误.

我编写了以下测试并使用我的编译器运行它(gcc(Homebrew gcc 5.2.0)5.2.0)

#include <stdio.h>

int f(int a, int b) {
  int c = a + b;
}

int main() {
   int x = 5, y = 6;

   printf("f(%d,%d) is %d\n", x, y, f(x,y)); // f(5,6) is 11

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

类似于我在工作中发现的代码,这默认返回函数中执行的最后一个表达式的结果.

我发现了这个问题,但对答案不满意.我知道-Wall -Werror可以避免这种行为,但为什么它是一个选项呢?为什么这仍然允许?

Bau*_*gen 12

"为什么这仍然允许?" 它不是,但一般来说,编译器无法证明你正在这样做.考虑这个(当然非常简化)示例:

// Input is always true because logic reason
int fun (bool b) {
    if (b) {
        return 7;
    }
}
Run Code Online (Sandbox Code Playgroud)

甚至这个:

int fun (bool b) {
    if (b) {
        return 7;
    }
    // Defined in a different translation unit, will always call exit()
    foo();
    // Now we can never get here, but the compiler cannot know
}
Run Code Online (Sandbox Code Playgroud)

现在第一个例子可以从最后流出,但只要函数"正确"使用它就永远不会; 而第二个不能,但编译器不能知道这一点.所以编译器会破坏"工作"和合法,尽管可能是愚蠢的代码,因为这是一个错误.

现在你发布的例子有点不同:这里,所有路径都流出端,所以编译器可以拒绝或者忽略这个函数.然而,它会破坏依赖于生产代码中的编译器特定行为的真实世界代码,并且人们不喜欢它,即使它们是错误的.

但最终,流出非void功能的结尾仍然是未定义的行为.它可能适用于某些编译器,但它不是,也绝不保证.

  • 评论不适用于扩展讨论; 这个对话已经[转移到聊天](http://chat.stackoverflow.com/rooms/89408/discussion-on-answer-by-baum-mit-augen-c-and-c-functions-without-a-返回-STAT). (2认同)

Oli*_*pro 5

这不是编译器中的错误,但代码显然格式错误。在 x86 架构上,(R|E)AX 用作累加器寄存器和返回值。

那么我们来看看一个完全没有优化的反汇编:https : //goo.gl/TihXpa

  • 你会看到 for 的代码f()确实使用 eax 来存储加法结果。

  • 但是......继续使用-O1(或任何更激进的优化级别)作为编译器选项(右上角的框),看看现在会发生什么。

...我们发现编译器正确地意识到该函数没有显式返回其结果,它只是变成了一个空操作。

因此,这段令人讨厌的代码是一个完美的例子,它可以像调试版本一样工作,但在应用任何优化时都会失败。