Function with a variable number of parameters without any explicit parameters

c++, function

Solution

Repeating from a comment:

It seems there is an interesting difference between C99 and C++11 here: C++11 allows a function declaration `void foo(...)` because the parameter-declaration-list in the parameter-declaration-clause is optional: [dcl.fct]

Function declaration:

`D1 (` parameter-declaration-clause `)` cv-qualifier-seqopt ref-qualifieropt exception-specificationopt attribute-specifier-seqopt

Parameters:

parameter-declaration-clause: parameter-declaration-listopt `...`opt parameter-declaration-list `, ...`

(Note how both the parameter-declaration-list and the `...` are separately opt here, meaning you can leave out one or the other or both. This interpretation is supported by clang++ and g++.)

In C99, this declaration is not allowed since the parameter-list is not optional in the parameter-type-list: 6.7.5/1

Function declaration:

direct-declarator `(` parameter-type-list `)`

Parameters:

parameter-type-list: parameter-list parameter-list `, ...`

As the `va_start` etc. macros/functions are inherited from C99, there's no way to use the arguments matched with the ellipsis with an empty parameter-declaration-list in C++.

Description of `va_start` in C99: 7.15.1.4

`void va_start(va_list ap,`parmN`);` [...] The parameter parmN is the identifier of the rightmost parameter in the variable parameter list in the function definition (the one just before the `, ...`). [...]

Emphasis mine. C99 assumes there's a parameter before the ellipsis, because it isn't legal in C99 to declare a function with an ellipsis but without parameters.

Yet, I can see two reasons to use a function with an ellipsis but w/o any parameters in C++:

Overload resolution. Matching arguments to an ellipsis leads to a very low ranking of the overload: An ellipsis conversion sequence is worse than any user-defined and standard conversion sequence [over.ics.rank]/2. This can be useful for metaprogramming:

char foo(int);
int  foo(...);

struct S{};
S s;
sizeof(foo(42));    // yields 1
sizeof(foo(s));     // yields sizeof(int)

Implementation-defined tricks. Your implementation may provide a mean to access those arguments matched with an ellipsis. E.g. see BobTFish's example

Problem

How to work in C++ with functions the following form: `void function(...) {}`? Do really need at least one implicit parameter?

Original source