3

I read a little about variadic functions in C/C++ and I found a thread that mentions to reuse a va_list in GCC you need to use a copy of it with va_copy and on the same thread they have suggested defining it with

#define va_copy(d,s) ((d) = (s)) Which means that it is simply assigning the value of va_list s to va_list d.

Wouldn't it be more readable to use va_list ap1 = va_list ap instead? What is the point of creating another function called va_copy?

  • 5
    The answer in that thread that suggests defining it as `((d) = (s))` does **not** suggest doing that for GCC or generally. It is a **specific** suggestion for MSVC. The C standard defines certain properties that `va_copy` and related features must satisfy, and C implementations accomplish those in different ways. In MSVC’s method of supporting variable argument lists, `((d) = (s))` may work. In others, it likely does not. – Eric Postpischil Mar 06 '20 at 14:11

1 Answers1

10

in GCC you need to use a copy of it with va_copy and on the same thread they have suggested defining it with

#define va_copy(d,s) ((d) = (s)) Which means that it is simply assigning the value of va_list s to va_list d.

That's not what they are saying in the other thread. In the J Jorgenson answer they state:

When attempting to reuse a va_list on GCC, one MUST use va_copy(), as the GCC implementation causes the va_list to be modified, causing the pointer to be positioned after last param after use by a v??printf() function.

Which means if you need to make a copy in GCC, you need to use va_copy

The answer that talks about implementing va_copy as

A previous question about the lack of va_copy in MSVC had some decent enough suggestions, including to implement your own version of va_copy for use in MSVC:

#define va_copy(d,s) ((d) = (s))

Is talking about MSVC which does not implement va_copy. The reason you would add such a "usless" macro is so that you can just use va_copy and get the correct behavior in both GCC and MSVC.

Wouldn't it be more readable to use va_list ap1 = va_list ap instead? What is the point of creating another function called va_copy?

Depending on how va_list is implemented it might not be "enough" to just do va_list ap1 = va_list ap. There can be thing that need to happen that can't be done with operator =. For instance, if va_list is a pointer type, you can't overload operator = for it so you need to make a named "function".

Community
  • 1
  • 1
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Though the wording may not imply, I am aware of this. What I question about is why not simply tell everyone to use `va_list ap1 = ap` which should do the same thing in a more intuitive way. – R3G3N3R4T0R Mar 06 '20 at 14:37
  • @R3G3N3R4T0R I've added to the answer about that. – NathanOliver Mar 06 '20 at 14:44
  • @R3G3N3R4T0R because you can't copy a `va_list` like that in most compilers, copying is implementation-defined and that kind of assignment is not portable. `va_copy()` is more portable, except for MSVC, where such direct assignment happens to be supported – Remy Lebeau Mar 06 '20 at 17:31