Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is returning va_list safe in C?

I'd like to write a function that has return type of va_list.

example: va_list MyFunc(va_list args);

is this safe and portable?

like image 616
Hayri Uğur Koltuk Avatar asked May 18 '12 07:05

Hayri Uğur Koltuk


People also ask

What is va_list in C?

va_list is a complete object type suitable for holding the information needed by the macros va_start, va_copy, va_arg, and va_end. If a va_list instance is created, passed to another function, and used via va_arg in that function, then any subsequent use in the calling function should be preceded by a call to va_end.

Is va_list a pointer?

The type va_list is used for argument pointer variables.

Where is va_list defined?

va_list is defined in stdarg. h as http://www.cplusplus.com/reference/cstdarg/va_list/ states. You can refer to the book "The Standard C Library" by Plauger if you need to know the ins and outs of the std libc.

How does va_ list work?

In the most usual stack-based situation, the va_list is merely a pointer to the arguments sitting on the stack, and va_arg increments the pointer, casts it and dereferences it to a value. Then va_start initialises that pointer by some simple arithmetic (and inside knowledge) and va_end does nothing.


2 Answers

va_list might (but is not guaranteed to) be an array type, so you can't pass or return it by value. Code that looks as if it does, might just be passing/returning a pointer to the first element, so you can use the parameter in the callee but you might be acting on the original.

Formally you can probably say that va_list is an entity type, not a value type. You copy it with va_copy, not with assignment or via function parameters/return.

like image 167
Steve Jessop Avatar answered Oct 18 '22 20:10

Steve Jessop


While you can definitely return such a value, I am not sure if the return value can be used in a useful way.

As the handling of va_lists requires special treatment (va_end() required after va_start() and va_copy()), and va_start/copy and va_end macros are even allowed to contain { } to enforce this pairing, you cannot call one without the other.

like image 39
glglgl Avatar answered Oct 18 '22 20:10

glglgl