C中的void函数返回什么?

时间:2014-02-02 17:49:34

标签: c function

#include <stdio.h>

void main()

{

    int k = m();

    printf("%d", k);

}

void m()

{

    printf("hello");

}  

输出
hello5

这里返回的void函数是什么? 如果没有printf()则输出为1。 这里发生了什么?

5 个答案:

答案 0 :(得分:7)

void函数不会返回任何内容。您的程序调用未定义的行为,因为它隐式定义m以返回类型int(在C89中,如果函数在声明之前被调用,则隐式假定它具有返回类型int) ,然后使用返回类型void定义它。

如果为m添加前向声明,编译器会正确地抱怨你正在尝试使用void函数的返回值,这是不可能的。

答案 1 :(得分:4)

在这两种情况下(void m,调用者期望intvoid main,调用者在C库期望int),这是未定义的行为,并且您的编译器应该把你弄掉,比如说[GCC 4.8 with -Wall]:

test.c:3:6: warning: return type of ‘main’ is not ‘int’
 void main()
      ^
test.c: In function ‘main’:
test.c:7:5: warning: implicit declaration of function ‘m’
     int k = m();
     ^
test.c: At top level:
test.c:13:6: warning: conflicting types for ‘m’
 void m()
      ^
test.c:7:13: note: previous implicit declaration of ‘m’ was here
     int k = m();
             ^

“隐式声明”的存在仅仅是为了与C1989之前的程序向后兼容,这些程序在此时已超过20年。如果你用更现代的风格编写了这段代码,你就会遇到一个很难的错误:

#include <stdio.h>

extern void m(void);

int main(void)
{
    int k = m();
    printf("%d", k);
    return 0;
}

void m(void)
{
    printf("hello");
}

test.c: In function ‘main’:
test.c:7:13: error: void value not ignored as it ought to be
     int k = m();
             ^

关键的补充是extern void m(void);行。在检查m错误时,不允许编译器查看main的定义,因此您需要一个前向声明来告诉它m的类型是什么。您还应该知道在C(但不是C ++)中,void m()表示“m需要未指定数量的参数”。要声明一个函数采用 no 参数,这就是你想要的,你必须写void m(void)

我相信你的特定系统正在发生的事情是你的代码正式忽略的printf的返回值被留在返回值寄存器中,因此被解释为{{1的返回值但是你不能依赖任何可预测的事情。这就是“未定义的行为”的含义。

答案 2 :(得分:2)

这是未定义的行为。

编译器允许您进行分配的原因是没有m可用的原型。发生这种情况时,C标准表示该函数必须返回int。因为在这种情况下实际的函数返回类型是void,所以行为是未定义的。您在变量k中获得的值完全是任意的。

答案 3 :(得分:1)

函数的返回值通常存储在一个CPU寄存器EAX for x86中。作为C它只是一个友好的汇编程序,您始终可以从寄存器中读取值。你会得到那里的一切。有效地,int k = m()告诉程序将寄存器EAX的值存储在变量k中。

答案 4 :(得分:0)

void m();中调用之前,您尚未声明main

某些编译器假定未知函数符号的返回类型为int(当然在编译时未知)。实际上,您的编译器可能已就此发出了编译警告。

如果您在 main之前声明此功能(声明应该),那么您可能会收到编译错误。