如果一个函数被声明为返回一个值(int),但在其所有执行路径中都没有显式地使用 return 语句返回一个值,那么程序的行为是“未定义的”(Undefined Behavior, UB)。

(图片来源网络,侵删)
这意味着编译器可能会发出警告,而程序运行时可能会出现不可预测的结果,
- 返回一个随机的垃圾值。
- 程序崩溃。
- 在某些特定环境下,可能返回一个固定的默认值(0),但这绝不能依赖。
详细解释
return 的基本作用
return 语句在 C 语言中有两个主要作用:
- 立即终止函数的执行:当代码执行到
return语句时,函数会立即停止,并将程序的控制权交还给调用该函数的地方。 - 将一个值返回给调用者:如果函数被声明为返回特定类型的值,
return语句后面必须跟着一个与函数返回类型兼容的表达式,这个表达式的值会被传递回调用者。
默认情况下的“缺失”问题
关键在于“默认”这个词,C 语言没有一个内置的、通用的“默认返回值”机制,编译器不会自动为你返回一个 0 或其他任何值。
让我们来看一个经典的例子:

(图片来源网络,侵删)
#include <stdio.h>
// 这个函数被声明为返回一个整数
int get_status() {
printf("Function get_status() is running.\n");
// 函数在这里结束,但没有 return 语句
// 这就是问题所在!
}
int main() {
int status = get_status();
printf("The returned status is: %d\n", status);
return 0;
}
编译和运行结果分析:
当你编译并运行这段代码时,很可能会得到类似下面的结果:
Function get_status() is running.
The returned status is: 6127658 // 或者其他任何随机数
为什么会这样?
- 函数调用约定:当
get_status()被调用时,它会在栈上分配空间用于存放返回值。 - 函数执行:函数执行
printf语句,然后到达函数的末尾。 - 未定义行为:由于没有
return语句,函数不会执行任何操作来设置这个返回值,这个返回值空间里保留的是上次使用这块内存时留下的“垃圾数据”(Garbage Value)。 - 返回垃圾值:
main函数中的status变量就被这个随机的垃圾值初始化了。
编译器警告

(图片来源网络,侵删)
一个好的编译器(如 GCC 或 Clang)在编译上述代码时,几乎肯定会发出警告:
warning: control reaches end of non-void function [-Wreturn-type]
这个警告非常关键,它告诉你:“你声明了一个要返回值的函数,但存在一条执行路径(在这里是函数的末尾)没有返回任何东西。” 这通常是代码中的一个错误。
正确的做法
对于有返回类型的函数
你必须确保在函数的每一个可能退出路径上都有一个 return 语句,并且返回正确的类型。
错误示例(有遗漏的路径):
#include <stdio.h>
int divide(int a, int b) {
if (b == 0) {
printf("Error: Division by zero!\n");
// b 为 0,函数在这里结束,但没有返回值
// 这会导致未定义行为
}
return a / b;
}
正确示例(处理所有路径):
#include <stdio.h>
// 返回一个错误码,或者使用更高级的方法(如指针、全局变量)
int divide(int a, int b) {
if (b == 0) {
printf("Error: Division by zero!\n");
return -1; // 返回一个特定的错误码
}
return a / b;
}
对于不返回值的函数 (void)
如果一个函数的目的只是执行一些操作(比如打印信息、修改全局变量或通过指针修改参数),而不需要返回一个计算结果,那么它应该被声明为 void 类型。
对于 void 函数,你可以使用 return; 来提前退出函数,但在函数末尾可以省略 return; 语句。
#include <stdio.h>
// 这个函数被声明为 void,表示不返回任何值
void print_hello() {
printf("Hello, World!\n");
// 函数在这里自然结束,不需要 return 语句
}
void print_message(const char *msg) {
if (msg == NULL) {
printf("Message is NULL.\n");
return; // 提前退出函数
}
printf("Message: %s\n", msg);
// 函数在这里自然结束
}
int main() {
print_hello();
print_message(NULL);
print_message("This is a test.");
return 0;
}
在这个例子中,print_hello 函数在末尾没有 return 语句是完全正确的,因为它被声明为 void。
| 函数声明 | 是否必须有 return 语句? |
如果没有 return 会怎样? |
|---|---|---|
int func(); |
是,在所有执行路径上都必须有。 | 未定义行为,可能返回垃圾值,导致程序逻辑错误或崩溃,编译器会警告。 |
void func(); |
否,在函数末尾可以省略。 | 行为正确,函数会正常执行到末尾并返回。 |
最佳实践:
- 仔细阅读编译器警告:
warning: control reaches end of non-void function是一个必须修复的信号。 - 为所有非
void函数的退出路径都提供return:确保逻辑完整,没有遗漏。 - 明确使用
void:当一个函数不返回值时,请务必将其声明为void,这会让代码意图更清晰,也能避免上述问题。
