C++ 对函数返回值感到困惑
这可能是原因:sum的值保存在寄存器C++ 对函数返回值感到困惑,c++,return-value,C++,Return Value,这可能是原因:sum的值保存在寄存器eax中,返回值也保存在eax中,因此Fun返回正确的结果。当程序通过if条件时,没有返回语句完成函数。您得到的数字是未定义行为的结果 0x004017E5 push %ebp 0x004017E6 mov %esp,%ebp 0x004017E8 sub $0x28,%esp 0x004017EB movl $0x1,-0xc(%ebp) 0x004017F2 cmpl $0x1,0x8(%ebp) 0x004017F6
eax
中,返回值也保存在eax
中,因此Fun
返回正确的结果。当程序通过if
条件时,没有返回语句完成函数。您得到的数字是未定义行为的结果
0x004017E5 push %ebp
0x004017E6 mov %esp,%ebp
0x004017E8 sub $0x28,%esp
0x004017EB movl $0x1,-0xc(%ebp)
0x004017F2 cmpl $0x1,0x8(%ebp)
0x004017F6 jle 0x40180d <Fun(int)+40>
0x004017F8 mov 0x8(%ebp),%eax
0x004017FB dec %eax
0x004017FC mov %eax,(%esp)
0x004017FF call 0x4017e5 <Fun(int)>
0x00401804 imul 0x8(%ebp),%eax
0x00401808 mov %eax,-0xc(%ebp)
0x0040180B jmp 0x401810 <Fun(int)+43>
0x0040180D mov -0xc(%ebp),%eax
0x00401810 leave
0x00401811 ret
如中所述,这是未定义的行为。使用g++时,我得到以下警告
int Fun(int x)
{
int sum=1.0;
if(x>1)
sum=x*Fun(x-1);
else
return sum;
return x; // return something here
}
在VisualC++中,默认情况下,警告被提升为错误
warning: control reaches end of non-void function [-Wreturn-type]
当我运行生成的可执行文件时,Fun(4)
给了我1861810763
那么为什么它可以在g++下工作呢?在编译期间,条件语句被转换为测试和跳转(或GOTO)。函数必须返回一些东西,编译器可能生成的最简单代码如下所示
error C4716: 'Fun' : must return a value
这与您的拆卸是一致的
当然,你不能依赖于未定义的行为,如VisualC++中的行为所示。出于这个原因,许多商店都有将警告视为错误的策略(也如a中所建议的)。只需从代码中删除
else
:
int Fun(int x)
{
int sum=1.0;
if(!(x>1))
goto RETURN;
sum=x*Fun(x-1);
RETURN:
return sum;
}
您的代码有几个错误:
- 您将
赋值为1.0(将隐式转换/转换),这不是错误本身,而是不雅观的int
- 在条件中有一个return语句,因此只有当
为true时才会得到返回
作为一个旁白,这里有一个更简洁/简洁的函数:对于这样简单的函数,你可以考虑并使用如下函数:
int Fun(int x)
{
int sum=1;
if(x>1)
sum=x*Fun(x-1);
return sum;
}
这是我用于阶乘的函数,在过去30年左右的时间里(从我的C天开始)我一直在库中使用它:)通常,EAX寄存器用于存储返回值,它也用于做其他事情 因此,在函数返回之前加载到该寄存器的任何内容都将是返回值,即使您不打算这样做 您可以使用-S选项生成汇编代码,并查看EAX在“ret”指令之前发生的情况。来自C标准: 从函数末尾流出相当于返回,而不返回 价值这将导致返回值时出现未定义的行为 功能 您的情况与此相同:
int factorial(int x){ return (x>1) ? (x * factorial(x-1)) : 1;}
它在我的机器上打印2。
这取决于时间和体系结构。返回值是最后一次表达式计算的结果,存储在eax寄存器中。这甚至不应编译。请发布一些编译过的东西。@nvoigt,在我看来应该是这样的(但MSVC不会IIRC)。不管怎样,未定义的行为意味着它似乎可以工作。@chris我总是使用WarningAsErrors编译,你是对的,这是“唯一”警告。欢迎来到未定义的奇妙世界behaviour@Dgrin91,调用自身后不会返回任何内容。这不是如何生成阶乘函数的问题,这是一个为什么这个实现是“有效的”的问题。德格林欢呼道:)现在,如果我们能让每个人都像你一样积极地批评。
int factorial(int x){ return (x>1) ? (x * factorial(x-1)) : 1;}
int fun1(int x)
{
int sum = 1;
if(x > 1)
sum++;
else
return sum;
}
int main()
{
int b = fun1(3);
printf("%d\n", b);
return 0;
}