Search code examples
cargumentsheader-filesvariadic-functions

Is including stdarg.h necessary for "..." argument in header files?


#ifndef WHATEVER_H
#define WHATEVER_H

void test(const char *format, ...); // would you have to #include <stdarg.h> for ... on argument, or is it ok if you don't use it

#endif // WHATEVER_H

So if I were to have a header file like this, where I needed to put ... as my argument for my void test function, would I have to include stdarg.h for the ... argument, or is it not mandatory?


Solution

  • The header does not need to include <stdarg.h> if the prototypes only include the ellipsis (, ...) notation. The code implementing the test() function will need to include <stdarg.h>, but the header declaring it need not.

    However, you should often consider creating a second function, void vtest(const char *format, va_list args); to match the test() function in the header, and then you do need <stdarg.h> to define the va_list type (and the implementation code no longer needs a separate #include <stdarg.h>). With the vtest() declaration in the header, the implementation of the test() function becomes trivial:

    void test(const char *format, ...)
    {
        va_list args;
        va_start(args, format);
        vtest(format, args);
        va_end(args);
    }
    

    This is particularly simple since there is no return value to relay, but returning a value is not very much harder. It's often a good idea to implement a variadic function like test() using this scheme, even if you don't expose the vtest() function — it is rather likely that you'll want the extra flexibility it provides eventually.