函数的返回值经常很令人困惑,有些函数有返回值,有些函数没有返回值,有返回值的函数也可以没有return语句而正常运行。
比如这样的代码一般是可以编译的,执行也正常:
int f(int a)
{printf("%d\n",a);
}
int main()
{f(5);
}
很奇怪是吗?
搞懂返回值究竟是什么就不奇怪了。
所有的CPU,处理函数的返回值都是这样的逻辑:
- 返回值放在一个寄存器里,一般是累加器
- 返回到调用处继续执行
return语句就是同时做了上面两件事。
那么没有return语句会怎么样?执行到函数结束一样会返回调用处继续执行。
虽然没有设置返回值,但CPU的寄存器还在啊,总是可以访问的(虽然值不是预期)。
累加器的值或许刚好是最后一个表达式的计算结果,刚好是期待的返回值,但更可能的是一个非预期的值,造成BUG。如果代码本身其实用不到返回值,不设置返回值当然没什么问题,但是为什么要声明为有返回值呢?
怀疑早期的程序员写程序很随意,胡写,所以C语言没法强制return。也或许是早期编译器没有智能到检查出没有返回值得代码分支,毕竟,在很多嵌套的if else里面识别出哪些是函数结束是很困难的。
但是不管怎么说,声明有返回值的函数没有正确设置返回值都是BUG,还好现代编译器都能给出警告。目前VS2022对一个return都没有作为错误,而没有return的分支只作为警告。
因为函数返回值放在寄存器里,是没法取地址的,是个“右值”。
如果函数返回值是个对象,寄存器放不下,那么编译器就会生成很复杂的代码来处理。一般建议不要返回对象,尽量通过指针参数来实现。
(这里是结束)