C ++ - 奇怪的函数返回值

时间:2016-10-07 20:48:37

标签: c++ function visual-studio-2015

当我突然问自己一个比我更复杂的问题时,我正在做一个简单的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?我知道应该有其他声明,但我很好奇没有它会发生什么

4 个答案:

答案 0 :(得分:3)

流出函数末尾会导致值返回函数中出现未定义的行为。您的程序行为未定义。

实际上,这意味着调用者将尝试根据正在使用的调用约定来读取返回的int,并且无法执行此操作。

答案 1 :(得分:1)

xy相等时,您不会返回任何内容。因此,当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结果。如果您同时跳过ifreturn分支并且不致电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;
    }
}