typedef struct s_node {
int val;
struct s_node *left_child;
struct s_node *right_child;
} NODE;
NODE *get_node_by_val(NODE *root, int searched_val) {
if (root != NULL) {
if (root->val == searched_val)
return root;
else if (root->val > searched_val)
get_node_by_val(root->left_child, searched_val); /**/
else if (root->val < searched_val)
get_node_by_val(root->right_child, searched_val); /**/
} else
return root;
}
Today we were talking about binary search trees. get_node_by_val
above searches for a NODE
in such a tree with its val
matching the given searched_val
. Recursively.
The point of contention is lines 12 and 14, marked with the /**/
.
At first sight, or to me at least it seems, they both should have been preceded by return
statements. Without the return
statement, my guess is that the subtree is indeed searched, but nothing is done with the value it returns. At some point, some call to get_node_by_val
will return (either NULL
or a pointer to the matching node), and this value will be passed to the caller, but this may happen levels of recursion down, in which the caller would have to pass this value back to its caller, and so on, all the way up to the first caller. But without the return
statement, only the caller 'immediately above' the one that returns gets that information.
Or so this would be my guess.
The problem is that this code WORKED (this happened earlier today in class, haven't tried it once again at home).
Why? How?
My uneducated guess is as follows: the deepest recursive call, the one that returns, puts its return value there on EAX. All of the calls above it don't return anything -- leaving EAX unchanged all the way up until the first caller returns (without returning anything).
At the end, the caller (the one that called get_nove_by_val
the very first time) sees EAX still containing the value that that deepest call put there, and figures it may as well be the value that the first call may have returned, and so everything works.
Is that what happens? Is this bad practice?