Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is va_list still used in C++? Or is it encouraged to use template<typename... T>?

In C, the only way to define a variable length of arguments is declaring its prototype with a ellipsis and use va_list, va_start, va_arg, va_end to extract them. Just like the printf series and the scanf series do.

In C++11, a new approach was introduced as below.

template <typename T, typename... MoreT>
void func(T arg, MoreT... args){
    // Do some stuff
    func(args);
}

What are the benefits and downsides of each method? Is either of them discouraged to be used or encouraged in C++?

like image 773
iBug Avatar asked Aug 26 '17 01:08

iBug


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.

What is Typename args?

typename... Args is called a template parameter pack, and Args... args is called a function parameter pack (Args is, of course, a completely arbitrary name and could be anything else).

What is va_start and va_end in C?

Description. The C library macro void va_start (va_list ap, last_arg) initializes ap variable to be used with the va_arg and va_end macros. The last_arg is the last known fixed argument being passed to the function i.e. the argument before the ellipsis. This macro must be called before using va_arg and va_end.

Does the VA accept evidence submitted through VBA?

Yes. VA accepts any evidence that a Veteran or his/her accredited representative chooses to submit in support of a claim. Once all evidence is received, VBA claims processors review and weigh the evidence overall as part of the decision-making process.

What is va_list type in C?

The va_list type is an array containing a single element of one structure containing the necessary information to implement the va_arg macro. The C definition of va_list type is given in figure below

Where can I get a C&P exam from VHA?

To supplement VHA’s internal capacity to conduct C&P exams, VBA has contracted with three primary vendors to provide exams across the country. This has expanded the agency’s ability to conduct exams in more places than just traditional VA Medical Centers and Outpatient Clinics.


3 Answers

C style variadic functions are heavily discouraged in C++. Styles vary but writing those kinds of functions will get you stoned in some circles (including mine), unless there's a truly exceptional reason.

As far as the trade-offs go, C style variadic functions are completely type unsafe. You could try to extract something from the variadic pack as the wrong type, which will result in a segfault. C++ variadic templates are strongly typed so this is not possible (unless of course you absolutely force it with a reinterpret_cast or something like that).

Beyond that, the C++ code will also typically (there are rare exceptions due to code bloat) perform better at run time. There's less indirection, more information for the compiler to work with. However, there may be longer compiler times, especially since variadic template functions (like all templates) generally must be defined in the header file, whereas C style variadics can be defined in the .cpp file.

In most C or C++ code (which is written for very high performance applications), the order of priorities would usually be correctness, then performance, then compile time. So most C++ devs believe that variadic templates are clear, clear winners here.

It is basically very similar to the comparison between a proper generic container in C++ using templates, and a void* based container in C++. Type safety + runtime performance, vs compile time performance (and .h vs .cpp).

like image 119
Nir Friedman Avatar answered Oct 01 '22 19:10

Nir Friedman


C++ strive to be more type safe than C e.g. nullptr, enum class provide more type-safe code. Compiler is your more intelligent friend.

Variadic template allow you to be more specific about type at compile-time itself while arguments in va_list et.al. C functions are evaluated at run-time

like image 27
JamesWebbTelescopeAlien Avatar answered Oct 01 '22 18:10

JamesWebbTelescopeAlien


There aren't a lot of benefits to variadic parameter functions, but there are some.

If you use a C variadic function, you get one compiled function that handles all the cases. If you use a C++ function with variadic templates, you get one compiled function per parameter combination. If code size is a consideration for your project, this can be a problem.

C++ variadic templates are type-safe, whereas C variadic functions are not. This means that the compiler usually won't enforce the type of the parameters that a function passes to a variadic function. GCC and Clang support some attributes that address common cases:

  • __attribute__((format())) tells the compiler that the variadic parameters use the printf/scanf convention, and will warn you when parameters don't match the format string that you've passed;
  • __attribute__((sentinel(N))) tells the compiler that the last variadic parameter should be the sentinel value.

It's still very much possible to screw up. For instance, the open function is variadic and requires a mask parameter as a third parameter when O_CREAT is specified, but it's frequently forgotten and neither of these __attribute__ extensions can address that.

The standard permits, but does not mandate, that implementations allow to pass non-POD types to C variadic functions; and when it does work, the semantics are implementation-defined. This means that you shouldn't do it if you want your code to be cross-platform.

Finally, it is typically harder to learn how to do C++ variadic templates right than it is to learn how to do C variadic functions.

like image 36
zneak Avatar answered Oct 01 '22 18:10

zneak