Variadic templates and typesafety

c++, c++11, type-safety, variadic-templates

Solution

Being safe, or type-safe, means that you can tell from looking at the source code whether your program behaves correctly.

The statement `std::cout << x` is always correct, assuming that `x` has a well-defined value (and isn't, say, uninitialized); this is something you can guarantee from looking at the source code.

By constrast, C is not safe: For example, the following code may or may not be correct, depending on the runtime input:

int main(int argc, char * argv[])
{
    if (argc == 3)
        printf(argv[1], argv[2]);
}

This is correct if and only if the first argument is a valid format string containing precisely one "`%s`".

In other words, it is possible to write a correct C program, but it's impossible to reason about the correctness just by inspecting the code. The `printf` function is one such example. More generally, any function that accepts variable arguments is most likely unsafe, as is any function that casts pointers based on runtime values.

Problem

There are several implementations of variadic templates printf function. One is this: ``` void printf(const char* s) { while (*s) { if (*s == '%' && *++s != '%') throw std::runtime_error("invalid format string: missing arguments"); std::cout << *s++; } } template<typename T, typename... Args> void printf(const char* s, const T& value, const Args&... args) { while (*s) { if (*s == '%' && *++s != '%') { std::cout << value; return printf(++s, args...); } std::cout << *s++; } throw std::runtime_error("extra arguments provided to printf"); } ``` and everywhere is said that this implementation is type-safe while the normal C (with variadic arguments va_arg) isn't. Why is that? What does it mean to be type-safe and what advantages has this implementation over a C printf va_arg one?

Original source