如果没有明确的"返回",函数将返回什么

lin*_*usz 3 c return function undefined-behavior

当我忘记编写return函数的子句时,我遇到了这个问题,但是没有警告或错误gcc.我修复了它,但开始想知道为什么函数会在没有a的情况下返回无意义的东西return.以下是我尝试的一些示例:

#include "stdio.h"
#include "stdlib.h"

int func1 () {
        int i;
        i = 2;
}

int func2 (int a) {
        int i = a+3;
}

int func3 () {
        int i;
        for (i = 0; i <= 1; i++);
}

int main(void) {
        int a = 0;
        int b = 0;
        int c = 0;
        a = func1();
        printf("a = %d \n", a);
        b = func2(a);
        printf("b = %d \n", b);
        c = func3();
        printf("c = %d \n", c);
}
Run Code Online (Sandbox Code Playgroud)

结果是:

a = 1 
b = 4 
c = 7 
Run Code Online (Sandbox Code Playgroud)

我的问题:

1)为什么这些结果?这有什么一般规则吗?
2)为什么要保留这个东西而不是报告错误?在某个地方可以某种程度上"有用"吗?

Dan*_*her 7

根据第6.9.1节第12段(C标准的N1570草案),这是不确定的行为:

如果}终止了函数,并且调用者使用了函数调用的值,则行为是未定义的.

如果调用者未使用返回值,则行为不是未定义的.

仅仅未定义的行为不需要诊断消息,因此编译器没有义务发出警告.gcc会警告你,如果你要求它(-Wreturn-type暗示-Wall),并且clang默认警告.

对于返回其他类型的函数void,return语句必须包含一个表达式,其值应根据6.8.6.4第1段返回:

return带有表达式的语句不应出现在返回类型为void的函数中.return没有表达式的语句只能出现在返回类型为void的函数中.


Sha*_*our 5

这是未定义的行为,将取决于所使用的调用约定.如果调用者期望寄存器中的结果,那么将使用寄存器中最后一个值.

编辑

草案C99标准中部分6.9.1 函数定义12说:

如果到达终止函数的},并且调用者使用函数调用的值,则行为是未定义的.

clang默认情况下gcc会发出警告并发出警告-Wall,一般情况下你应该启用警告.