函数是否有可能返回与其显式返回值不同的值?

sne*_*ker -10 c language-lawyer

int my_func(void) {
    if(/*condition*/) {
        return 1;
    }
    else if (/*other condition*/) {
        return 2;
    }
    
    return 3;
}

int x = my_func();
Run Code Online (Sandbox Code Playgroud)

是否x保证始终是 3 个可能值之一?
以标准或 POSIX 或其他合法来源的引用形式提供证明。如果没有这样的来源,请提供逻辑证明(gcc/汇编)。

Tim*_*mmm 8

还有一些其他的可能性:

  • 它可能永远不会返回(例如无限循环、段错误)
  • 内联汇编也会导致返回
  • 它可以长跳转到其他代码
  • 在 C++ 中你可能会有例外
  • 未定义的行为基本上可能导致任何事情发生

但一般来说是的,x必须是返回值之一。

这与 POSIX 无关。

未定义行为的一种值得注意的形式是到达应该返回但没有返回的函数的末尾。默认情况下,这甚至不是 GCC 的警告:

int foo(int a) {
  if (a == 1) { return 1; }
  if (a == 2) { return 2; }
}

foo(3);
Run Code Online (Sandbox Code Playgroud)


Per*_*xty 7

标准中最重要的声明是:

如果return执行带有表达式的语句,则表达式的值将作为函数调用表达式的值返回给调用者。如果表达式的类型与其出现的函数的返回类型不同,则该值将被转换,就像通过分配给具有该函数的返回类型的对象一样。

return因此,如果达到其中一项语句,则会返回相关值。

另一个答案提供了为什么可能没有达到其中任何一个的原因,包括对实际条件下调用的函数的调用abort()或在函数中的调用。exit()if

代码具有占位符(例如/* condition */),这些占位符可以执行代码或调用超出简单条件逻辑的函数。

在这个答案中,我挑选了标准中证明主要结论的要点。

因此,条件是保证执行的条件能够评估(不会终止程序或无限期地执行)语句的定义if是确定返回这些值之一所需的唯一另一件事:

在这两种形式中,如果表达式比较不等于 0,则执行第一个子语句。在该else形式中,如果表达式比较等于 0,则执行第二个子语句。

其中所说的“两种形式”指的是普通形式ifif-else形式。

两种形式都出现在示例中。有一个if- elseandelse语句本身就是一个if语句。

除此之外,它比 C 标准的声明更合乎逻辑的推论得出结论:(如果函数返回)在具有已定义行为 (*) 的程序中,它必须返回这 3 个值(1、2 或 3)之一。

(*) 不包含任何具有未定义行为的内容。

参考:https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf