当我突然问自己一个比我更复杂的问题时,我正在做一个简单的min()函数
我创建了一个有效的函数,并且想法省略两个数字之间的条件。这是我的功能:
int min(int x, int y) {
if (x > y) {
return y;
}
else if (x < y) {
return x;
}
}
所以它适用于不同的数字,如果我把2和3放在里面,它将返回2。 但是,当我把两次相同的号码时,会发生什么?例如:2和2
两者都不是&gt; 2和2&lt; 2是有效的,所以它只是返回......什么都没有?
我认为,我编译程序(VS2015),得到一个关于不测试每个案例(正常)的警告,当它运行时...它输出2.为什么?
在与人交谈之后(并检查此功能的ASM代码),有人检查了Valgrind发生了什么,并且正如他告诉我的那样,它可能是内存泄漏。我不知道它是如何工作的,那么为什么不返回任何值使它返回2?返回哪2个?
我还测试了其中一个条件是否因为某种原因而出现了一个简单的std :: cout,但没有一个主题是真的,所以这不是关于“{1}}
的”简化“那么这里到底发生了什么?
[编辑]我不想知道如何“修复”它,因为这对我来说非常明显。问题是,为什么我得到2?我知道应该有其他声明,但我很好奇没有它会发生什么
答案 0 :(得分:3)
流出函数末尾会导致值返回函数中出现未定义的行为。您的程序行为未定义。
实际上,这意味着调用者将尝试根据正在使用的调用约定来读取返回的int
,并且无法执行此操作。
答案 1 :(得分:1)
x
和y
相等时,您不会返回任何内容。因此,当x
等于y
时,程序会有未定义的行为。
使用:
int min(int x, int y) {
if (x > y) {
return y;
}
else {
return x;
}
}
答案 2 :(得分:1)
要了解其行为的方式和原因,您需要学习此处使用的调用约定。
我认为典型的x86 C / C ++调用约定是push
(如ASM命令)参数堆栈,call
函数,然后是pop
结果。如果您同时跳过if
个return
分支并且不致电push
,则不会生成pop
条指令。但是来电者仍然会void
。它会流行什么?无论在那个地方的堆栈上是什么,这可能是任何事情 - 没有办法知道。我认为它会破坏堆栈,或者更确切地说 - 将其置于其他堆栈用户不期望的状态。由于你的堆栈现在已经混淆了,程序可能会完全停止工作,就像我看到的那样。结论:永远不要让return
函数在没有eax
语句的情况下退出。
更新:我使用Godbolt查看了实际的程序集(例如https://godbolt.org/z/8emYlB),我现在可以看到我对通常使用的调用约定的错误;看起来堆栈不用于返回值,return
寄存器是。因此,至少缺少[Designer(typeof(ParentControlDesigner))]
public partial class InnerControl : UserControl
不会导致堆损坏,但是仍然会得到一个未定义的返回值 - 无论那时发生在累加器寄存器中的是什么。
答案 3 :(得分:0)
您只需要添加else
语句,因为2 = 2既不符合if(x > y)
条件,也不符合else if(x < y)
条件。所以它无法返回任何东西。只需添加else
并返回相同的x值。
int min(int x, int y)
{
if (x > y)
{
return y;
}
else
{
return x;
}
}