2016-10-07 44 views
1

我做一个简单的MIN()函数时,我突然问自己这有一点问题更加复杂,比我虽然C++ - 古怪的函数返回值

我创建了一个有效的功能,并得到了主意,省略这两个数字之间的一个条件。这里是我的功能:

int min(int x, int y) { 
    if (x > y) { 
     return y; 
    } 
    else if (x < y) { 
     return x; 
    } 
} 

所以它完全适用于不同的号码,如果我把2和3的内部,它会返回2. 但发生什么事,当我把两个时间相同数量?例如:2和2

2> 2和2 < 2都是无效的,所以它只是返回...什么都没有?

即使我编译了程序(VS2015),我得到了一个关于未测试每个案例(正常),以及何时运行...的警告输出2.为什么?

在与人交谈(并检查此函数的ASM代码)后,有人向Valgrind查询了发生的事情,并且他告诉我,看起来它可能是内存泄漏。我不完全知道它是如何工作的,那么为什么不返回值使它返回2?哪2个返回?

如果这些条件之一是由于某种原因,用一个简单的std ::法院真的,但没有主题是真实的,所以这不是什么“简化”与if (x > y) {...} else {...}

我还测试了什么是真正的在这里发生?

[编辑]我不想知道如何“修复”它,因为它对我来说很明显。问题是,为什么我得到2?我知道应该有一个else语句,但我很好奇没有它会发生什么

+1

如果你启用了警告编译这一点,你会看到类似'警告:控制到达非空function'结束。如果你没有看到这样的警告,你应该改变你的编译器设置,让你看到它们,因为它非常有用。这里的关键是你没有最后的其他条款。 –

+1

我真的不明白为什么人们想要在未定义的行为上赌博,当他们可以修复代码时... –

+0

@Baum mit Augen建议的重复不回答为什么有问题的函数返回'2'的问题。 –

回答

1

xy相等时,您不会返回任何东西。因此,当x等于y时,程序具有未定义的行为。

用途:

int min(int x, int y) { 
    if (x > y) { 
     return y; 
    } 
    else { 
     return x; 
    } 
} 
+1

这是值得一提的一点,也是实现这一点的正确方法。 –

+0

@JuanTomas:它被标记为C++。正确的方法是'std :: min'。或者至少是单行的:'return x

+0

我认为练习的要点是编写你自己的'min()'。但是,三元运营商可以说是更好的方式。我认定的是错误的'else if'。 –

1

要了解如何以及究竟为什么它的行为,你需要研究这里使用的调用约定

相信典型的x86 C/C++调用约定是push(如在,则ASM命令)的参数压入堆栈,call的函数,然后pop结果。如果您跳过两个if分支并且不呼叫return,则不会生成push指令。但来电者仍然会pop。它会弹出什么?无论结果在那个地方,这可能是任何东西 - 没有办法知道。而且我认为这样会破坏堆栈,或者更确切地说 - 将其置于其他堆栈用户不期望的状态。这个程序可能会完全停止正常工作,就像我看到它一样,因为现在你的堆栈已经混淆了。底线:永远不要让void函数退出而没有return声明。

+0

@GuillaumeRacicot:你看不出这正是我解释的吗?他已经知道函数没有明确地返回任何东西。他问为什么它仍然回来2。 –

3

在函数结尾处流动导致返回值函数中出现未定义的行为。你的程序的行为是未定义的。

实际上这意味着调用者将尝试根据正在使用的任何调用约定来读取返回的int,并且不能这样做。

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; 
    } 
}