Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does va_copy() require va_end()?

Tags:

c

c99

When dealing with variable arguments, is it just va_start() that needs a matching va_end() call, or does va_copy() require a matching va_end() too, i.e

void foo(char *x, ...)
{
  va_list l,c;

  va_start(l,x);
  va_copy(c,l);

  ---
  va_end(c); //is this correct ?
  va_end(l);
}
like image 519
user1255770 Avatar asked Jun 18 '14 10:06

user1255770


People also ask

Why is Va_end needed?

va_end is used to do cleanup. You don't want to smash the stack, do you? Each invocation of va_start() must be matched by a corresponding invocation of va_end() in the same function. After the call va_end(ap) the variable ap is undefined.

What is Va_copy?

The va_copy() macro copies the (previously initialized) variable argument list src to dest. The behavior is as if va_start() were applied to dest with the same last argument, followed by the same number of va_arg() invocations that was used to reach the current state of src.

What is Va_end?

The va_end macro performs cleanup for an ap object initialized by a call to va_start or va_copy. va_end may modify ap so that it is no longer usable. If there is no corresponding call to va_start or va_copy, or if va_end is not called before a function that calls va_start or va_copy returns, the behavior is undefined.

How does Va_arg work in C?

In the C Programming Language, the va_arg function fetches an argument in a variable argument list. The va_arg function updates ap so that the next call to the va_arg function fetches the next argument. You must call the va_start function to initialize ap before using the va_arg function.


1 Answers

Yes, every copy and the original, requires va_end() to be called. Your example is correct, the order of your va_end() calls can be reversed.

From ISO/IEC 9899:201x:

7.16.1.3 The va_end macro

The va_end macro facilitates a normal return from the function whose variable argument list was referred to by the expansion of the va_start macro, or the function containing the expansion of the va_copy macro, that initialized the va_list ap. The va_end macro may modify ap so that it is no longer usable (without being reinitialized by the va_start or va_copy macro). If there is no corresponding invocation of the va_start or va_copy macro, or if the va_end macro is not invoked before the return, the behavior is undefined.

The last sentence states that every va_start or va_copy must be accompanied by an va_end before returning.

like image 80
this Avatar answered Oct 19 '22 18:10

this