We help IT Professionals succeed at work.

Is it OK to return a local variable from a static function?

deleyd
deleyd asked
on
153 Views
1 Endorsement
Last Modified: 2019-03-05
I found this code in the Open Source code for Wireshark, and it appears it is returning a local variable, which I thought was not allowed, since the variable goes out of scope once the routine returns.

However, since it's a static routine, maybe that makes it OK,

Is it OK to return a local variable from a static function?

static GSList* local_interfaces_to_list_win(void)
{
	GSList *interfaces = NULL;
...
	return interfaces;
}

Open in new window

(This is C code.)
Comment
Watch Question

evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
It's returning a pointer by value. That's fine. It is no different than just returning an int, for example. There's nothing special about a pointer. They're also just values.

The same semantics apply to static functions as non static functions.
Fabrice LambertConsulting
CERTIFIED EXPERT
Distinguished Expert 2017

Commented:
Keep in mind that the returned value is a copy, so local variable or not, it is fine.
deleydSoftware Engineer

Author

Commented:
Is the value the pointer points to guaranteed to be there?
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
No. Whatever it points to must be kept still in scope or it'll be a dangling pointer. Ignore the fact the function is static, it doesn't change the normal rules regarding life time and scope of variables.
CERTIFIED EXPERT
Top Expert 2016
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
Fabrice LambertConsulting
CERTIFIED EXPERT
Distinguished Expert 2017

Commented:
@saraband:
Classic pointers nightmare in C, since nothing can ensure it is valid, it is up to the dev's discipline.

But that's not the OP's question.
CERTIFIED EXPERT
Top Expert 2016

Commented:
Classic pointers nightmare in C

actually, that is not my experience. i am working with C designed code since decades and although there is a lot of bad code produced by some programmers, a serious and controlled management of pointers is crucial for commercial products and you hardly can be successful without strict design rules. if pointers were allocated but not freed in the same context, the code will run out of control. you will get leaks or crashes or both. while porting the code to c++ allows a better pointer management, this is not an automatism. so i have seen c++ code which returned pointers to local objects (and crashed sometimes but not always ...) and i have seen really good c code with a straight design and easy to maintain. summarized: good and bad code can be produced with any language.

Sara
CERTIFIED EXPERT

Commented:
>>  it appears it is returning a local variable, which I thought was not allowed, since the variable goes out of scope once the routine returns.
Just checking.. I think I know what you may have read to give rise to this concern. Do you need further explanation as to what kind of a return would raise a flag at code review, and why it would raise a flag?
evilrixSenior Software Engineer (Avast)
CERTIFIED EXPERT

Commented:
deleyd, after reading the replies, do you now understand why the pointer that is being returned by value (copy) is safe? Remember that a pointer is really nothing more than a special integer value and so returning a pointer is no different that returning an int or a long. It's returned by copy.

Now, that begs the question, what about what it points to? Well, that's a different story. Whatever it points to has to be in scope (as in it must be constructed and either be stored somewhere in the stack or on the heap). What's important to understand here is that there is a difference between the pointer itself being valid and what it points to being valid. Once you get your head around those different semantics you'll be well on your way to C enlightenment :)

Seriously, though. Don't sweat it. Pointers can be confusing. The trick is to remember that a pointer is not something special. It is not magical. It is just a very special type of integer and, as such, it has all the same copy semantics as any int type (such as short, int, long, etc). The only special thing about a pointer is that you can dereference it to access what it points to. Other than that, it's just an integer type.
deleydSoftware Engineer

Author

Commented:
I see I failed to include where the pointer gets set. Let me investigate that.
deleydSoftware Engineer

Author

Commented:
OK it uses the GLib library. I'll assume it's written correctly and returns something that doesn't disappear on us.
GSList *
g_slist_prepend (GSList *list,
                 gpointer data);

Open in new window

deleydSoftware Engineer

Author

Commented:
Thank you everyone!
CERTIFIED EXPERT
Top Expert 2016

Commented:
OK it uses the GLib library. I'll assume it's written correctly and returns something that doesn't disappear on us.
g_slist_prepend adds a new GSList node.

a GSList structure defines a node of a standard singly-linked-list, with 2 members: a void pointer to arbitrary data (typedef'd as gpointer) and a pointer to the next GSList node. each GSLIST pointer is either a single node or a GSList element of GSList linked-list. an empty list is defined by setting the GSList pointer to NULL.

the function g_slist_prepend inserts a new GSList element as new start element. it returns a pointer to the newly created start node. because of that it is important that the returned pointer was stored by the caller because the new start node IS THE new GSList which also must be passed as first argument to all other GSList functions including the g_slist_free_full function which would free all the memory. if the start node got lost there would be memory leaks. if you check the statement where g_slist_prepend was called, you will see that the pointer returned was assigned to the pointer variable passed as first argument:

// assume you have some data in an array
struct Data data[MAX_DATA] = { 0 };  
filldata(data, MAX_DATA);
// "create" an empty list
GSList * plist = 0;
// add one node and get a valid pointer to the start node back
// pass a void pointer to data element as 2nd argument
plist = g_slist_prepend (plist, &data[0]);
// insert next start node to list
plist = g_slist_prepend (plist, &data[1]);
....

Open in new window


generally it is not bad design if c code uses pointers for a container management. the usage of GSList functions is not so much different to a c++ singly-linked-list class beside that you have to free memory by call (vs. automatical deletion by destructor).

Sara
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.