为什么没有return语句的main函数返回值12?

时间:2010-09-16 13:18:44

标签: c linux unspecified-behavior

我写了一个打印表格的程序。我没有在main函数中包含返回语法,但每当我输入echo $时仍然如此?它显示12。

我的源代码:

#include <stdio.h>


int main(void)
{
    int ans,i,n;
    printf("enter the no. : ");
    scanf("%d",&n);

    for(i=1;i<=10;i++)
    {
        ans = n*i;
        printf("%d * %d = %d\n",n,i,ans);
    }
}

我没有写回12,但每次执行程序时它都会返回12。

感谢。

4 个答案:

答案 0 :(得分:20)

正如swegi所说,它是未定义的行为。正如Steve Jessop等人所说,它是一个未指定的值,直到C89,并在C99中指定(观察到的行为不符合C99)

在大多数环境中实际发生的事情是,上一个printf的返回值保留在用于返回值的寄存器中。

因此,对于n == 0,它将是11;如果n是一位数,则为12,对于两位数n为14,对于三位数n为16,等等。

答案 1 :(得分:18)

回答是因为所有现有的答案都表明它是未定义的行为,这是不正确的,所以我没有任何东西可以投票。

在C89中(感谢pmg引用draft standard),5.1.2.2.3:

  

从初始通话返回到   主要功能是   相当于用值调用exit函数   由main函数返回作为其参数。如果}   到达终止主要功能,   终止状态返回给主机环境   未指定的。

在C99中,引用n1256,5.1.2.2.3:

  

如果主要的返回类型   function是一种兼容的类型   int,从最初的调用返回到   主要功能相当于   用the调用exit函数   main函数返回的值为   它的论点;达到那个   终止main函数返回一个   值为0.如果返回类型不是   兼容int,终止   状态返回给主机   环境未明确。

因此,它不是“未定义的行为”:它的行为就像main函数返回一样,但在C89中,返回的值不是由标准指定的。对于您的示例程序,在您的实现中,返回的值似乎始终为12,可能是因为Ben Voigt说。因为你在linux上,所以编译你的代码可能不是一个很大的改变(或者无论如何,使用gcc几乎兼容的C99模式编译它)。

对于除main以外的任何返回值的函数, 是未定义的行为,除非调用者不使用返回值(n1256) ,6.9.1 / 12):

  

如果终止函数的}是   达到了,功能的价值   呼叫由呼叫者使用   行为未定义。

我不确定是否应该提及main的初始调用被排除在此一般规则之外。它不需要:从标准的POV,该调用没有调用者,所以我认为函数调用的值不是“调用者使用”,即使它成为终止状态对于该计划。

答案 2 :(得分:1)

如果您完全熟悉汇编语言,您可能会记得函数的“返回值”是通过EAX寄存器传递的。

在这种情况下,正在从EAX读取返回值。在这种情况下,恰好是12。

但是,你没有明确地设置这个值,它只是来自其余代码的一个工件(或者只是偶然)。

如前所述,这绝对是undefined behavior。如果您只是好奇为什么会这样,请考虑这个解释。

但在任何情况下都不要试图故意将此值用作有意义的事物。

答案 3 :(得分:0)

你的程序在没有返回任何内容时会导致未定义的行为,因此调用程序通常会在程序返回时获取eax寄存器的值(在x86上,x64上的rax),这是通常从上次使用eax(通过返回值的函数或仅基于寄存器的变量)的垃圾,在这种情况下,它可能是printf写入stdout缓冲区的char的数量