C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Allow trailing commas in function calls

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 17 Aug 2025 13:53:48 -0400
On Sun, Aug 17, 2025 at 12:45 PM Jeremy Rifkin via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
> Hi,
> In general more trailing commas would be nice and useful.
> The motivation you’ve shared, though, isn’t sufficient.
>
> [...]
> > It can also be useful for parsing partially written function calls,
> allowing tools like clangd to provide information about the
> function.
>
> Tools like clangd are free to do whatever they want to handle partially
valid grammar fragments, with or without language support.


In fact, I imagine that the current status quo is better for detecting
whether a function call is "partially written" or not.
Given (where `^` represents the cursor's position)
    auto v = my::function(^
the IDE will often autocomplete the parens to
    auto v = my::function(^)
and then if you keep typing
    auto v = my::function(a, b,^)
the IDE might reasonably give you some suggestions for the third argument.
But if `my::function(a, b,)` were to become a syntactically valid function
call with two arguments, then the IDE's autocompletion job would become
harder, not easier.

Several years ago, there were contributors on std-proposals wanting to use
an "empty argument" to mean something else, such as "use the default
argument for this position," i.e. something like this:
    int func(int x, int y);
    int func(int x, int y = 1, int z = 2);
    int main() {
      auto v1 = func(1, , 3); // same as func(1, 1, 3)
      auto v2 = func(1, 2, ); // same as func(1, 2, 2); same as func(1, 2)
except unambiguous
   }
The general consensus was that the syntax `f(a,b,)` if it's valid at all
probably ought to mean the same thing as `f(a,b)` for consistency with
other languages such as Python and JavaScript; but if there are still
people wanting to repurpose the syntax to mean something else, then maybe
it's better to just keep it invalid for now, pending further and deeper
investigation.

See also
https://github.com/eisenwave/cpp-proposals/issues/46
https://github.com/cplusplus/papers/issues/1818
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0562r2.pdf

Footnote: The problem with trailing commas in member-initializer-lists,
identified by Richard Smith in June 2024, which delayed/deferred/derailed
adoption of P0562R2, was:
  // https://godbolt.org/z/EPE1EWcWM


* struct X {}; struct Y : X { Y() : A<b<c>(), {*

* // some text here, perhaps }*

Today, in C++26, the "some text here" part is definitely a
braced-initializer-list. But if that comma is allowed to be a trailing
comma, then the "some text here" part could be *either* a
braced-initializer-list or a compound-statement (i.e. the body of Y::Y()).
The compiler can't know which one it is, until it sees whether the code
after that `}` looks like: either—
    template<bool> using A = X;
    static constexpr int b = 0;
    static constexpr int c = 0;
  };
or—
>{} {}
    template<auto, int> using A = X;
    template<class> struct b {};
    struct c {};
  };

So the compiler doesn't know in what manner to parse the "some text here"
stuff — as a comma-separated list of expressions or as a series of
semicolon-terminated statements.

–Arthur

Received on 2025-08-17 17:54:04