43

I am used to declaring variadic functions like this:

int f(int n, ...); 

When reading The C++ Programming Language I found that the declarations in the book omit the comma:

int f(int n...); // the comma has been omitted 

It seems like this syntax is C++ specific as I get this error when I try to compile it using a C compiler:

test.c:1:12: error: expected ‘;’, ‘,’ or ‘)’ before ‘...’ token int f(int n...);

Is there any difference between writing int f(int n, ...) and int f(int n...)?

Why was this syntax added C++?

7
  • 2
    en.cppreference.com/w/cpp/utility/variadic Commented Feb 29, 2016 at 19:37
  • 1
    Another reference that describes this peculiarity. Look at the bottom of the page regarding printz(...). Commented Feb 29, 2016 at 19:38
  • 1
    I believe that this feature was added in C++ because of the operator nature of .... This allowed for more consistent syntax in the language with added features like parameter packs. Commented Feb 29, 2016 at 19:51
  • 2
    @callyalater This... "feature"... predates C++11. You can see the relevant rule still in N1905 Commented Feb 29, 2016 at 21:08
  • 3
    I am used to declaring variadic functions like this: I hope you don't do that on a regular basis. Writing such functions regularly crushes the type safety of your program and opens up huge oppertunities for programmer driven bugs. Commented Mar 1, 2016 at 9:26

4 Answers 4

38

According to § 8.3.5.4 of the C++ standard (current draft):

Where syntactically correct and where “...” is not part of an abstract-declarator, “, ...” is synonymous with “...”.

In short, in C++ ... (ellipsis) is an operator in its own right and so can be used without the comma, but use of the comma is retained for backwards compatibility.

Sign up to request clarification or add additional context in comments.

13 Comments

... and, in my view, for clarity. int n... looks like it should have something to do with parameter pack expansion. Or, at the very least, it looks like the ... is related to the n.
@PreferenceBean I never said it did. The point is that they weren't thinking of that back then because parameter pack expansion wasn't a thing. Until five years ago, the paramater pack thing wouldn't have been an issue. Understanding the history of a language is important because it helps to explain these little obscurities.
@Pharap What was the possible purpose of allowing the omission of the comma?
@Barry Presumably because somebody thought it was a good idea somewhere along the line. That's one of those questions only the people who accepted it into the spec could answer. If I had to guess I'd have to say to make it appear more like the use of ellipses in language or simply because it's a fraction of a second quicker to write.
@Barry because that's the wrong question. What was the possible reason for adding an unnecessary comma? See my answer for historical overview.
|
29

Currently, both of these declarations have the same meaning:

int f(int n, ...); int f(int n ...); 

This leads to an issue where the following two declarations are both legal, yet have wildly different meanings:

template <class... T> void f(T...); // function template with parameter pack template <class T> void f(T...); // variadic function 

Once C++11 introduced variadic templates, it is much more likely that the second declaration is a programmer error rather than lazily omitting the comma. As a result, there was a proposal to remove the latter from the language (P0281), but it was apparently rejected.

2 Comments

Very interesting to note. But I disagree with your characterization as "lazy omittion". Not having it has always been the normal case. An extra comma is defined as a synonym, for compatibility with C declarations, or perhaps you add it to look better. But it's something added not something omitted.
Omitting the comma is deprecated since C++26 through PR176: The Oxford variadic comma.
15

With int f(int n, ...); and int f(int n...);, as you can see, both , ... and ... has the same meaning. Comma is optional.

But this int printz(...); is valid in C++ while int printz(,...); is not (at least one named parameter must appear before the ellipsis parameter). That's why you can have just (...), even though the arguments passed to such function are not accessible.

Comments

6

As I recall from the time, C++ indeed defined variadic function signatues as you note. Later, the rapidly evolving C language (on the journey from K&R to ANSI) introduced prototypes or new-style function declarations that also declared parameters inside parens after the function name. But, with two notable differences: the comma before the ellipses, and the need for the abomination of (void) to indicate an empty parameter list (to preserve backward compatibility of the empty parens as an old style declaration).

Looking through my archives, I find The C++ Programming Language original edition "reprinted with corrections July 1987" shows:

    argument-declaration-list:
        arg-declaration-listopt
...opt

    arg-declaration-list:
       arg-declaration-list
, argument-declaration
       argument-declaration

There is no form to accept the now-optional comma. Note that the arg-declaration-list is a comma-separated and this doesn't hang out to provide a comma after the list and before the next (different) thing.

This is the most natural way to write this. If you want a comma, you need explicitly , ... in the first production, as two distinct (possibly whitespace separated) tokens.

As C's efforts to proper standardization progressed, C++ compilers started accepting the C versions as well to allow easy use of the C standard header files.

Why did the C designers add the comma when it implies a less sensible grammatical role of the ellipses as a fake parameter placeholder? I never found out.

2 Comments

So your argument is that the comma is bad because it makes the grammar rules [slightly] harder to write?
No, that's not the point and the observation indicates that the point is missing. It's the same as the exclaimation point: it was never needed and not designed in. So why would you suppose that "leaving it out" is even a thing?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.