01-07-2010, 11:31 AM
William Forbes Wrote:Quote:So please tell me of a case where it makes sense to return a pointer from a function.
How about when parsing a linked list that is statically declared.
Ok this is drifting off topic... I apologize for that.
A simple version of such code would be:
Code:
BOOL find_node (Node* linked_list, Data key, Node** result)
{
BOOL found = FALSE;
Node* iterator;
for(iterator = linked_list; iterator != NULL; iterator = iterator->next)
{
if(iterator->data == key)
{
*result = iterator;
found = TRUE;
break;
}
}
return found;
}
This code has the big advantage that it won't touch any pointers in the caller function unless it found the node.
Had you returned a pointer, you would overwrite variables in the caller function even though you found nothing:
Code:
/* Bad practice example */
Node* find_node (Node* linked_list, Data key);
...
Node* node = fail_safe_data;
...
node = find_node (list, key);
/* oops, node is overwritten to NULL or some such if function fails */
This is particularly poor practice in safety-critical applications, where the design should be so that functions preserve data if they fail.
However, I think the main issues with returning a pointer to static are the mentioned issues: order of evaulation, broken encapsulation, and multi-threading. Consider this:
Code:
if (find_node(list, this) == find_node(list, that)) /* Ask for trouble. Possibly violates a number of MISRA rules. */
Dangerous code, as you can't know whether the left or right function call will be evaluated first. If find_none() alters something in the list, the above code will contain a subtle bug that would either break the whole program or make it non-portable. Had you returned the pointers through the parameter list, you would never end up with that order of evaluation issue, as it would rule out the dumb idea of calling the functions in the same expression:
Code:
Node* result1;
Node* result2;
find_node(list, this, &result1);
find_node(list, that, &result2);
if(result1 == result2)
<t></t>