non-void function works fine even without executing return

强颜欢笑 提交于 2020-01-30 06:58:27

问题


I'm a computer science college student. Yesterday, I have a class about Binary Search Tree using C++. We are taught by lab assistants in that class.

They define the node in the tree as a struct like this :

struct Data{
    char name[15];
    int age;
    Data *left,*right;
};

and they give us a code to search within the BST like this:

// temp is current node, name is the value of the node to be searched for.
Data* search(Data *temp,char name[]) {
    if(strcmp(temp->name,name)>0)
        search(temp->left,name);
    else if(strcmp(temp->name,name)<0)
        search(temp->right,name);
    else
        return temp;
}

I notice that code is wrong. If the function gets into the first or the second if block, it will not execute any return statement.

But when the lab assistant run the code, it works just fine.

I thought maybe this behaviour is compiler specific. But when I tried that code on gcc, the function also work fine. (our university uses microsoft visual c++ compiler)

Can anyone explain what is happening? why is this code working?

PS: ignore other errors such as when the node is empty, the value is not found, etc.


回答1:


It's just undefined behavior.

It appears to work because there's one register that holds the return value. In the deepest paths of the recursion tree, the temp is moved into that register, and never cleared or changed afterwards, so that register will contain the correct node until the first call returns.

When the first call returns, the calling context checks that register for the return value, which happens to be correct. But you shouldn't rely on this. It's not safe to assume it will always work.




回答2:


Typically, you've got one hardware register used to return value from a function (that'd be %EAX on i686, for instance). If the last thing you did in your function is calling another function and the intended return value is the result of that function, it may occur that %EAX value hasn't been trashed and is nicely retrieved by the caller.

That's subject to many hypothesis, however, and you shouldn't expect it to be reliable in any way. First of all, the compiler can detect that you're not using the return value of search(), so it might decide to optimize away that call if it has hints about search() having no side effects. If it's capable of inlining the search call, it could partly optimize it away.

There may be other architectures (iirc, that'd be the case with IA64) where the calling convention are more subtle, and where the registers used for returning values in one function are not the same as in the caller function. So your code relies on platform-dependent details to be working while it's supposed to be a high-level (and portable) language.



来源:https://stackoverflow.com/questions/10548779/non-void-function-works-fine-even-without-executing-return

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!