You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中未显式return的函数为何printf能输出对应值?

C语言非void函数无return语句返回值现象说明

示例代码

#include <stdio.h>

int fun1(void);
int fun2(void);
int fun3(void);
int x;  //global variable

void main(){
    x=10;
    printf("x = %d\n",x);
    printf("x = %d\n",fun1());
    printf("x = %d\n",fun2());
    printf("x = %d\n",fun3());
}


fun1(void){
    x = x+10; //global
}

fun2(void){
     int x;
     x = 1;  //local
     return x;
}

fun3(void){
    x = x+10;  //local
}

运行输出

x = 10
x = 20
x = 1
x = 30

核心疑问

声明为返回int类型的fun1、fun3没有写显式return语句返回值,为什么printf还是能输出20、30这类符合预期的数值?

原因解释

  • 首先要明确:这是典型的未定义行为(Undefined Behavior),不是C语言标准保证的合法效果,你当前看到的输出只是特定编译器、特定编译选项、特定硬件架构下的巧合,换环境结果可能完全不同,甚至程序直接崩溃。
  • C语言标准明确规定:如果返回值类型不是void的函数,在执行到函数体结束的}时没有通过return语句返回确定值,调用方尝试读取该函数返回值的行为没有任何标准约束,编译器可以生成任意逻辑的代码,不需要对结果负责。
  • 你当前看到的“正确返回”是x86平台下常见编译器的实现习惯导致的:x86架构下,C函数返回int类型值时,约定把返回值存放在EAX通用寄存器中。fun1和fun3里最后执行的操作是对全局变量x做加法赋值,这个运算的结果会临时存放在EAX寄存器里,函数结束前没有其他指令修改EAX的值,调用方按约定从EAX读返回值时,就刚好读到了修改后的全局x的数值。
  • 这种巧合非常脆弱:只要你调高编译优化等级、换ARM/RISC-V等其他架构的编译器、在函数末尾加几行其他运算代码,返回值马上会变成不可预期的随机值。现在主流编译器(GCC、Clang)开启-Wall警告选项时,会直接对“非void函数无return语句”的写法抛出警告,开启-Werror后会直接阻止编译。
  • 额外说明:原示例代码存在多处不符合现代C标准的写法:一是fun1、fun3定义时省略返回值类型,这是已经被废弃的C89隐式int规则,C99及之后的标准不再支持这种写法;二是void main()不是C标准规定的合法main函数签名,标准写法为int main(void);三是fun3内没有定义局部变量x,注释标注操作的是local变量属于笔误,实际操作的是全局变量x。

内容的提问来源于stack exchange,提问作者Israk Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 19:29:00