Trailing comma in constructor initializer list

1,718 views
Skip to first unread message

Myriachan

unread,
Jul 27, 2015, 6:02:06 PM7/27/15
to ISO C++ Standard - Future Proposals
To fix a minor annoyance for a long time, I think that the initializer list following a constructor prototype should allow a trailing comma with nothing after it. This also makes initializer lists consistent with enums (C++11) and aggregate initializers (C++03?). The purpose is to assist when editing, and helping when using "svn blame" or the equivalent for your version control.

Yes, I have seen the workaround of putting commas on the next line, but this doesn't match some coding styles.

class dword_table
{
public:
dword_table(std::size_t count)
try
: m_array(new std::uint32_t[count]),
m_count(count),
{
}
catch (std::bad_alloc)
{
std::fprintf(stderr, "out of memory allocating %zu dwords", count);
throw;
}
...
};

Melissa

Thiago Macieira

unread,
Jul 27, 2015, 7:11:19 PM7/27/15
to std-pr...@isocpp.org
I would favour this, even if for the simple reason that it would be another
argument against writing:

dword_table(std::size_t count)
: m_array(new std::uint32_t[count])
, m_count(count)
, m_other(1)
{
}

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358

Christopher Horvath

unread,
Jul 27, 2015, 7:22:53 PM7/27/15
to std-pr...@isocpp.org
What's wrong with:

my_class(int something)
    : m_something(something)
    , m_something_else(nullptr)
    , m_init(false) {
}

I think it looks nice, reads well, cuts-and-pastes well, etc.  Is there something here other than personal preference?


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Thiago Macieira

unread,
Jul 27, 2015, 7:26:15 PM7/27/15
to std-pr...@isocpp.org
On Monday 27 July 2015 16:22:51 Christopher Horvath wrote:
> What's wrong with:
>
> my_class(int something)
> : m_something(something)
> , m_something_else(nullptr)
> , m_init(false) {
> }
>
> I think it looks nice, reads well, cuts-and-pastes well, etc. Is there
> something here other than personal preference?

Personal preference. I find lines starting with a comma to be poor taste.

Christopher Horvath

unread,
Jul 27, 2015, 7:33:12 PM7/27/15
to std-pr...@isocpp.org
I like the way they line up.  This is the only place I use this idiom.  Apologies for the noise and the distasteful code!

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.

Richard Smith

unread,
Jul 27, 2015, 8:08:09 PM7/27/15
to std-pr...@isocpp.org
On Mon, Jul 27, 2015 at 4:22 PM, Christopher Horvath <black...@gmail.com> wrote:
What's wrong with:

my_class(int something)
    : m_something(something)
    , m_something_else(nullptr)
    , m_init(false) {
}

I think it looks nice, reads well, cuts-and-pastes well, etc.  Is there something here other than personal preference?

Yes. This convention has a special case for the first line (it has a colon not a comma) and for the last line (since you are putting the open brace there), so adding/removing/reordering fields is not as simple as reordering the lines.

Arthur O'Dwyer

unread,
Jul 27, 2015, 9:22:33 PM7/27/15
to ISO C++ Standard - Future Proposals, myri...@gmail.com
The actual wording change seems to be trivial:

I suppose a formal proposal is still required, though, since otherwise there'd be no way for committee members to register opposition?

–Arthur

Myriachan

unread,
Jul 27, 2015, 10:13:47 PM7/27/15
to ISO C++ Standard - Future Proposals, arthur....@gmail.com
On Monday, July 27, 2015 at 4:22:53 PM UTC-7, Christopher Horvath wrote:
What's wrong with:

my_class(int something)
    : m_something(something)
    , m_something_else(nullptr)
    , m_init(false) {
}

I think it looks nice, reads well, cuts-and-pastes well, etc.  Is there something here other than personal preference?


Nothing is wrong with your way, except the location of the brace (adding to the list requires deleting the brace).  It's just personal preference.  I think beginning with a comma is weird, like Thiago thinks, but you may not feel that it's weird.  Use whichever, IMO.



I like the way they line up.  This is the only place I use this idiom.  Apologies for the noise and the distasteful code!
 

That it's the only place this idiom gets used is to me a symptom of what I see as a problem: in two other similar cases, enums and aggregate initializers, you don't use it.

We wouldn't want to allow it for the comma operator, I would think, because otherwise either a new overload (unary postfix operator ,) would be required or a special rule to ignore it would be required.

For function calls, it would be awkward, because it kind of looks like another parameter is there.  Python does allow this, though.  (Python, however, gives the single parameter (x,) different meaning to (x); the comma forces tuple/argument parsing instead of merely a parenthesized expression.)

For function prototypes (including as part of definitions), it could be useful for very long argument lists that are written one per line; this is an uncommon edge case, though.  Similar for template parameters.  (What the heck you're doing with a template parameter list so large, I don't know >.<)

Regarding being distasteful, it's just a visual preference.  Both are quite readable.  I would get a lot more distaste for not encapsulating classes properly or undefined behavior. =^-^=


On Monday, July 27, 2015 at 6:22:33 PM UTC-7, Arthur O'Dwyer wrote:
The actual wording change seems to be trivial:

I suppose a formal proposal is still required, though, since otherwise there'd be no way for committee members to register opposition?

–Arthur


Shouldn't that have happened before committing to the draft?  Just curious; I'm not sure what the protocol should be.

By the way, I apologize for the double post.  Apparently, Google's posting form doesn't have bounce protection--the two "clicks" were from my thumb on my phone 1/8 second part.

Melissa

Richard Smith

unread,
Jul 27, 2015, 10:45:17 PM7/27/15
to std-pr...@isocpp.org, Arthur O'Dwyer
This change has not been committed to the draft.

It looks like github treats all forks of a repository as being part of the same repository internally, and you can put any of those forks into a URL, even if the named repository doesn't contain the specified commit. The commit is actually on the mem_initializer_list_comma branch in the repository Quuxplusone/draft, and not in the standard's repository at all.
 
By the way, I apologize for the double post.  Apparently, Google's posting form doesn't have bounce protection--the two "clicks" were from my thumb on my phone 1/8 second part.

Melissa

--

Arthur O'Dwyer

unread,
Jul 28, 2015, 2:22:17 AM7/28/15
to Richard Smith, std-pr...@isocpp.org
On Mon, Jul 27, 2015 at 7:45 PM, Richard Smith <ric...@metafoo.co.uk> wrote:
> On Mon, Jul 27, 2015 at 7:13 PM, Myriachan <myri...@gmail.com> wrote:
>>
>> That it's the only place this idiom gets used is to me a symptom of what I
>> see as a problem: in two other similar cases, enums and aggregate
>> initializers, you don't use it.

Yep, that's the obvious argument in favor, IMO.

>> On Monday, July 27, 2015 at 6:22:33 PM UTC-7, Arthur O'Dwyer wrote:
>>>
>>> https://github.com/cplusplus/draft/commit/5417003045bad50705847f3d20ff72d78aeec32a
>>>
>>> I suppose a formal proposal is still required, though, since otherwise
>>> there'd be no way for committee members to register opposition?
>>
>> Shouldn't that have happened before committing to the draft?  Just
>> curious; I'm not sure what the protocol should be.
>
> This change has not been committed to the draft.
>
> It looks like github treats all forks of a repository as being part of the
> same repository internally, and you can put any of those forks into a URL,
> even if the named repository doesn't contain the specified commit. The
> commit is actually on the mem_initializer_list_comma branch in the
> repository Quuxplusone/draft, and not in the standard's repository at all.

Yes. I was surprised, myself, to notice that I'd posted what looks like a link into the official repo! Indeed, it really points into my own fork of the repo. My question still stands, though: would this require
- a whole proposal, with N1234 number and all?
- an informal motion of some sort at Kona?
- a pull request against cplusplus/draft?
(Listed in order of decreasing formality and decreasing likelihood. ;))

Thanks,
–Arthur

Bo Persson

unread,
Jul 28, 2015, 7:20:54 AM7/28/15
to std-pr...@isocpp.org
> a link into the official repo! Indeed, it /really/ points into my own
> fork of the repo. My question still stands, though: would this require
> - a whole proposal, with N1234 number and all?
> - an informal motion of some sort at Kona?
> - a pull request against cplusplus/draft?
> (Listed in order of decreasing formality and decreasing likelihood. ;))
>

This being a language change, the committee would probably like a formal
paper discussing the pros and cons. Like if this code

my_class(int something)
: m_something(something), m_something_else(nullptr),
{ }

should still be accepted, or if I just forgot the third initializer.
Perhaps my phone rang at that point?


A pull request by itself is only for "editorial changes", where the
editor can accept obvious small fixes for formatting, typos or any
misapplied earlier changes.



Bo Persson


Arthur Tchaikovsky

unread,
Jul 28, 2015, 8:37:18 AM7/28/15
to std-pr...@isocpp.org
I genuinely cannot believe what I'm reading in this discussion.
Do C++ really has no other *bigger* problems to solve, that we can
discuss if comma should be allowed at the end of constructor's
initializer list, because some one has preferences towards it?
Seriously?
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposal...@isocpp.org.
> To post to this group, send email to std-pr...@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>


--
Yours sincerely
Artur Czajkowski

Arthur Tchaikovsky

unread,
Jul 28, 2015, 8:38:17 AM7/28/15
to std-pr...@isocpp.org
And it simply look weird having a comma and nothing following it. It
looks like there is something missing.

David Krauss

unread,
Jul 28, 2015, 8:41:32 AM7/28/15
to std-pr...@isocpp.org

> On 2015–07–28, at 8:37 PM, Arthur Tchaikovsky <atch...@gmail.com> wrote:
>
> I genuinely cannot believe what I'm reading in this discussion.
> Do C++ really has no other *bigger* problems to solve, that we can
> discuss if comma should be allowed at the end of constructor's
> initializer list, because some one has preferences towards it?
> Seriously?

Maybe there are a lot of people sharing this preference.

Regardless of the number of messages in this thread, the committee effort should be low. It should be a small proposal, a brief meeting discussion, and a minor change to the normative grammar spec.

Arthur Tchaikovsky

unread,
Jul 28, 2015, 8:42:47 AM7/28/15
to ISO C++ Standard - Future Proposals, arthur....@gmail.com, myri...@gmail.com


On Tuesday, 28 July 2015 03:13:47 UTC+1, Myriachan wrote:
 I think beginning with a comma is weird, like Thiago thinks, but you may not feel that it's weird.  Use whichever, IMO.

I think ending with comma is even weirder.
 

Vadim Petrochenkov

unread,
Jul 28, 2015, 8:55:41 AM7/28/15
to ISO C++ Standard - Future Proposals, atch...@gmail.com
I find it unproductive to discuss where to allow or disallow trailing comma based on formatting styles, but otherwise it's a small but genuine problem.
I like how they resolved it in Rust - trailing separators are consistently allowed in all list contexts, thus making any macro or code generation work simpler + no bikeshedding about every particular case, as a bonus.

Ville Voutilainen

unread,
Jul 28, 2015, 9:00:39 AM7/28/15
to std-pr...@isocpp.org
On 28 July 2015 at 15:41, David Krauss <pot...@gmail.com> wrote:
> Regardless of the number of messages in this thread, the committee effort should be low. It should be a small proposal, a brief meeting discussion, and a minor change to the normative grammar spec.

And then wait for every implementation on the planet to implement this
change, and
every other tool that desperately tries to grok C++ code. The overall
effort is anything
but low, so the question is whether the benefit is worth the effort.
Thus far the rationale
provided doesn't convince me.

Arthur Tchaikovsky

unread,
Jul 28, 2015, 9:24:37 AM7/28/15
to ISO C++ Standard - Future Proposals, pot...@gmail.com
@David Krauss
That's assumption. Can you provide empirical data? Otherwise, assumptions, personal preferences, bike sheds etc.

Vadim Petrochenkov

unread,
Jul 28, 2015, 9:28:19 AM7/28/15
to ISO C++ Standard - Future Proposals, ville.vo...@gmail.com
The same can be said about every DR resolution - they are usually small, not very practically significant, but still have to be implemented by everyone.
Irrespectively to this particular proposal, these kinds of arguments are usually applied selectively (based on my experience of reading this list) and look like warding off work. 
(Sorry for meta.)

Ville Voutilainen

unread,
Jul 28, 2015, 9:43:37 AM7/28/15
to ISO C++ Standard - Future Proposals
On 28 July 2015 at 16:28, Vadim Petrochenkov
<vadim.pet...@gmail.com> wrote:
> The same can be said about every DR resolution - they are usually small, not
> very practically significant, but still have to be implemented by everyone.

I daresay I disagree with the claim that DR resolutions are usually
not practically
significant, compared to this particular idea.

> Irrespectively to this particular proposal, these kinds of arguments are
> usually applied selectively (based on my experience of reading this list)
> and look like warding off work.
> (Sorry for meta.)

In this case, I'll call it warding off useless nonsense, rather than
warding off work.

Matthew Woehlke

unread,
Jul 28, 2015, 10:06:01 AM7/28/15
to std-pr...@isocpp.org
On 2015-07-28 09:00, Ville Voutilainen wrote:
> And then wait for every implementation on the planet to implement
> this change, and every other tool that desperately tries to grok C++
> code.

IMHO that ship has sailed... anyone - besides compiler authors - trying
to parse modern C++ by themselves is just insane. Use clang. Just C++11
is infernally complicated, and as you note, trying to keep up with
changes is near impossible. Much better to use a full compiler to do the
parsing for you and work with the resulting AST than try to write your
own parser.

(Incidentally, I'd be in favor of the change; as others have indicated,
this makes it really obnoxious and unnecessarily difficult to make VCS
edits of initializer lists, and is inconsistent with enums and
aggregates which allow the trailing comma.)

--
Matthew

Ville Voutilainen

unread,
Jul 28, 2015, 10:41:46 AM7/28/15
to ISO C++ Standard - Future Proposals
On 28 July 2015 at 17:05, Matthew Woehlke <mwoehlk...@gmail.com> wrote:
> On 2015-07-28 09:00, Ville Voutilainen wrote:
>> And then wait for every implementation on the planet to implement
>> this change, and every other tool that desperately tries to grok C++
>> code.
>
> IMHO that ship has sailed... anyone - besides compiler authors - trying
> to parse modern C++ by themselves is just insane. Use clang. Just C++11
> is infernally complicated, and as you note, trying to keep up with
> changes is near impossible. Much better to use a full compiler to do the
> parsing for you and work with the resulting AST than try to write your
> own parser.

So let's just break every working parser, good or not, in order to
provide a nice-to-have feature to make 'git/svn/whatever blame' prettier?
I don't find that a convincing argument. Same goes for macros.

> (Incidentally, I'd be in favor of the change; as others have indicated,
> this makes it really obnoxious and unnecessarily difficult to make VCS
> edits of initializer lists, and is inconsistent with enums and
> aggregates which allow the trailing comma.)

I fail to agree with the "obnoxious and unnecessarily difficult" part.
The consistency
argument sounds remotely plausible.

I guess Richard should take the idea to Core, if he thinks it's
viable. I can't imagine
my supporting this idea.

Bo Persson

unread,
Jul 28, 2015, 10:47:40 AM7/28/15
to std-pr...@isocpp.org
But it IS consistent with other comma separated items, like parameters.

What about

template
<
class one,
class two,
class three,
>
struct x;

or

void f(int one,
int two,
int three,
);


Just playing the devil's advocate :-)


Bo Persson


Matthew Woehlke

unread,
Jul 28, 2015, 11:02:27 AM7/28/15
to std-pr...@isocpp.org
On 2015-07-28 10:47, Bo Persson wrote:
> On 2015-07-28 16:05, Matthew Woehlke wrote:
>> I'd be in favor of the change; as others have indicated, this makes
>> it really obnoxious and unnecessarily difficult to make VCS edits
>> of initializer lists, and is inconsistent with enums and aggregates
>> which allow the trailing comma.
>
> But it IS consistent with other comma separated items, like parameters.
>
> What about
>
> template
> <
> class one,
> class two,
> class three,
> >
> struct x;

As already noted, it's fairly uncommon to have long template parameter
lists of the sort that would most benefit from such relaxation of the
grammar rules. I think this is less interesting, though I don't see
myself objecting to such a change.

> or
>
> void f(int one,
> int two,
> int three,
> );

I've run into refactoring headaches with parameter lists less often than
initializer lists, but even so, I'd be willing to entertain such a
proposal. (And I'll reiterate something else already pointed out; Python
already allows this.)

Something I think deserves consideration is why e.g. enums and
aggregates support a trailing comma. Someone obviously felt those cases
were worthy; why some but not others?

--
Matthew

Arthur Tchaikovsky

unread,
Jul 28, 2015, 11:18:03 AM7/28/15
to ISO C++ Standard - Future Proposals, mwoehlk...@gmail.com
But why would you even want to write such code? The idea of trailing comma is at best weird and useless.

Matthew Woehlke

unread,
Jul 28, 2015, 11:55:03 AM7/28/15
to std-pr...@isocpp.org
On 2015-07-28 11:18, Arthur Tchaikovsky wrote:
> But why would you even want to write such code? The idea of trailing comma
> is at best weird and useless.

Because it eliminates a special case for the last item in a list. This
can be critical if you're using macros to generate a list. It also means
that, if you have one item per line, the previous line does not change
when adding a new item, which is important when using a VCS (which
should be the case for any non-trivial code).

So, your "useless" assertion is false. I'd also argue that your "weird"
assertion is dubious, as ending each item-line with a comma, even the
last one, makes for greater consistency. And there may be other
benefits; those are just the ones I can think of offhand.


Consider:

enum Animals {
Dog,
- Cat
+ Cat,
+ Emu
};

vs.

enum Animals {
Dog,
Cat,
+ Emu,
}

Which more clearly conveys the relevant change?

--
Matthew

Arthur Tchaikovsky

unread,
Jul 28, 2015, 12:04:32 PM7/28/15
to std-pr...@isocpp.org
But this is not C++ problem but Source Control Tools. They need to be
improved not C++ needs to adjust.

dgutson .

unread,
Jul 28, 2015, 12:29:11 PM7/28/15
to std-proposals
On Tue, Jul 28, 2015 at 1:04 PM, Arthur Tchaikovsky <atch...@gmail.com> wrote:
> But this is not C++ problem but Source Control Tools. They need to be
> improved not C++ needs to adjust.

Real world code uses version control systems which part of their job
is to let people know
which lines have changed. A VCS will not have a way to distinguish
whether to show or not to show
a line as "different" depending it has a last comma or not; it's not a
matter of making VCSs smarter.
Who’s got the sweetest disposition?
One guess, that’s who?
Who’d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?

Myriachan

unread,
Jul 28, 2015, 12:38:35 PM7/28/15
to ISO C++ Standard - Future Proposals
C++ doesn't live in a vacuum. Source control exists, and I dare say most C++ users use it.

The change to allow comma at the end of enum lists is a relatively recent one; C++11 I believe. That change had to go through the same process, the same resistance, etc., and yet it made it. Minor stuff does get accepted >.<

Melissa

Thiago Macieira

unread,
Jul 28, 2015, 12:40:12 PM7/28/15
to std-pr...@isocpp.org
Arthur, your second emails prove *exactly* why this is being discussed.

Your first email showed your annoyed reaction to this list discussing a trivial
matter when so many other important things need to be discussed.

And then you fell for the lure of the discussion, went to the dark side and
joined the discussion :-)

On Tuesday 28 July 2015 13:38:15 Arthur Tchaikovsky wrote:
> And it simply look weird having a comma and nothing following it. It
> looks like there is something missing.
>
> On 7/28/15, Arthur Tchaikovsky <atch...@gmail.com> wrote:
> > I genuinely cannot believe what I'm reading in this discussion.
> > Do C++ really has no other *bigger* problems to solve, that we can
> > discuss if comma should be allowed at the end of constructor's
> > initializer list, because some one has preferences towards it?
> > Seriously?

Thiago Macieira

unread,
Jul 28, 2015, 12:42:45 PM7/28/15
to std-pr...@isocpp.org
I can answer with two bytes: >>

Besides, comma at the end of enums is permitted. Why not at the end of other
lists?

However, comma at the end of a parameter list?

foobar(1,
2,
3,
4,
);

Arthur Tchaikovsky

unread,
Jul 28, 2015, 12:43:58 PM7/28/15
to ISO C++ Standard - Future Proposals, daniel...@gmail.com
And I repeat:
It is a tool job to do its job properly, not language to adjust.

Arthur Tchaikovsky

unread,
Jul 28, 2015, 12:47:23 PM7/28/15
to ISO C++ Standard - Future Proposals, myri...@gmail.com
Nor those tools either. They need to do the job properly not expecting from language to adjust.

So what were those argument/s in favor of having comma at the end of enum? I'm really interested to read it.

Brent Friedman

unread,
Jul 28, 2015, 12:50:55 PM7/28/15
to std-pr...@isocpp.org
And I repeat:
It is a tool job to do its job properly, not language to adjust.

C++ is also a tool, so this argument holds no weight for me.

 

Arthur Tchaikovsky

unread,
Jul 28, 2015, 12:59:08 PM7/28/15
to ISO C++ Standard - Future Proposals, fourt...@gmail.com
It is a tool but for different purpose. VCS are tools and their job is (one of many) to properly show changes. This is not C++ job to adjust to those tools, because in this scenario C++ is not a tool but a subject to which tool is applied. Surely you will not try to invent better form of plank in order to be able to hit nails more precisely? It's a hammer's job to do it. Not planks. Both are tools, but in different scenarios. I'm a son, but also a father. Different situations, different roles assumed.

Arthur Tchaikovsky

unread,
Jul 28, 2015, 1:03:38 PM7/28/15
to ISO C++ Standard - Future Proposals, myri...@gmail.com
Another argument against? Comma logically separates things and that's how most people I believe understand its role. Comma at end of logical *entity* is:
a) weird
b) useless
c) illogical

from C++ standpoint.

On Tuesday, 28 July 2015 17:38:35 UTC+1, Myriachan wrote:

Brent Friedman

unread,
Jul 28, 2015, 1:51:02 PM7/28/15
to std-pr...@isocpp.org
Surely you will not try to invent better form of plank in order to be able to hit nails more precisely? 

"Plank manufacturers" absolutely alter how they construct wood planks to make hammering less error prone. You cut the plank in such a way [along the grain] that the wood will grip the nail better. You prefer types of wood less likely to splinter or warp under pressure.

However, I think it's more useful to remain on the topic of C++ rather than discussing the generally unrelated discipline of carpentry.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.

Arthur Tchaikovsky

unread,
Jul 28, 2015, 1:53:00 PM7/28/15
to ISO C++ Standard - Future Proposals, fourt...@gmail.com
Exactly, that's why I repeat:
It is tool that parses C++ to do a proper job, not C++ job to adjust to that tool.

Matthew Woehlke

unread,
Jul 28, 2015, 2:05:37 PM7/28/15
to std-pr...@isocpp.org
On 2015-07-28 12:04, Arthur Tchaikovsky wrote:
> But this is not C++ problem but Source Control Tools. They need to be
> improved not C++ needs to adjust.

<satire>
POSIX is a terrible API for file system manipulation. Therefore, rather
than providing standard interfaces in C++ to perform I/O operations, we
should insist that POSIX change to conform to what C++ thinks it The One
True Way to implement file systems and disk I/O.
</satire>

You are not going to change every generic textual comparison
tool/library in existence (and there are a LOT of them, most based on
the Unified Diff standard which is at issue here). As such, assertions
that doing so is the "proper" course of action are out of touch with
reality.

For that matter, I'll reiterate Ville's argument, inverted; it's much
more effort to change text comparison tools than to change C++ parsers,
if only because there are so very many more of them.

--
Matthew

Thiago Macieira

unread,
Jul 28, 2015, 2:44:45 PM7/28/15
to std-pr...@isocpp.org
On Tuesday 28 July 2015 09:59:08 Arthur Tchaikovsky wrote:
> It is a tool but for different purpose. VCS are tools and their job is (one
> of many) to properly show changes. This is not C++ job to adjust to those
> tools, because in this scenario C++ is not a tool but a subject to which
> tool is applied.

In an ideal world, the VCS tool would have a parser for every single language
under the Sun and would interpret when a change is meaningful or not.

in the real world, none of them do. Supporting every single language is just
not feasible. Heuristics may or may not be enough, and they may or may not be
misleading too. For example, in most languages, leading whitespace changes are
no-ops, so they could be discarded from view. But not in all languages.

> Surely you will not try to invent better form of plank in
> order to be able to hit nails more precisely? It's a hammer's job to do it.
> Not planks.

Unless your plank is made of a material that is too hard, in which case you
must replace it. That's similar here: we have to adapt to the real world.

(And don't call me Shirley - https://www.youtube.com/watch?v=ixljWVyPby0)

> Both are tools, but in different scenarios. I'm a son, but also
> a father. Different situations, different roles assumed.

Thiago Macieira

unread,
Jul 28, 2015, 2:45:34 PM7/28/15
to std-pr...@isocpp.org
On Tuesday 28 July 2015 10:53:00 Arthur Tchaikovsky wrote:
> It is tool that parses C++ to do a proper job, not C++ job to adjust to
> that tool.

True. But which tool are we talking about that parses C++?

VCS tools don't.

Ville Voutilainen

unread,
Jul 28, 2015, 5:37:51 PM7/28/15
to ISO C++ Standard - Future Proposals
On 28 July 2015 at 19:42, Thiago Macieira <thi...@macieira.org> wrote:
>> And then wait for every implementation on the planet to implement this
>> change, and
>> every other tool that desperately tries to grok C++ code. The overall
>> effort is anything
>> but low, so the question is whether the benefit is worth the effort.
>> Thus far the rationale
>> provided doesn't convince me.
> I can answer with two bytes: >>

I fail to see how that's even remotely similar to what we're discussing here.

> Besides, comma at the end of enums is permitted. Why not at the end of other
> lists?

If we want to allow a trailing comma in a ctor-initializer list, what about the
base-specifier list?

struct X :
A,
B,
C,
{};

Morwenn

unread,
Jul 28, 2015, 6:34:37 PM7/28/15
to ISO C++ Standard - Future Proposals, myri...@gmail.com
I would be for such a change, for the simple reason that it makes it easier to generate code.
If I'm not mistaken, that's *the* reason why trailing commas are already allowed in many contexts.

And let's be honest, that's not one or two tools: we all needed to generate code at some point, be it from macros or from another tool.

Not having to special-case stuff allows to write generation tools more easily and that's a huge benefit offered by trailing comma.

David Krauss

unread,
Jul 28, 2015, 10:03:19 PM7/28/15
to std-pr...@isocpp.org

> On 2015–07–28, at 9:00 PM, Ville Voutilainen <ville.vo...@gmail.com> wrote:
>
> On 28 July 2015 at 15:41, David Krauss <pot...@gmail.com> wrote:
>> Regardless of the number of messages in this thread, the committee effort should be low. It should be a small proposal, a brief meeting discussion, and a minor change to the normative grammar spec.
>
> And then wait for every implementation on the planet to implement this
> change, and
> every other tool that desperately tries to grok C++ code. The overall
> effort is anything
> but low, so the question is whether the benefit is worth the effort.
> Thus far the rationale
> provided doesn't convince me.

Compilers are labor-saving devices. Implementation work is well spent if it saves time for users. What we have in this thread is customers agreeing that they’re wasting time because this C++ grammar quirk chokes other tools in the chain. The customer is usually right, unless there’s an argument that the feature could be dangerous.

Constructor initializers are a lot like statements, so they should have similar punctuation. They map 1:1 to nonstatic member declarations, which typically have dedicated lines. If you were to write the initializations as assignments in the function body, you wouldn’t even think of running the statements together on one line. Mem-initializers do the same job. That’s why they’re like enumerator declarations and aggregate initializers, and unlike function arguments. Base classes also often get listed line by line, but multiple inheritance is uncommon.

In a perfect world, we’d have some way to terminate member initializers with semicolons, yet evaluate them in the order of their declarations. The syntax is already a compromise, and this tweak to let commas act more like semicolons seems quite appropriate.

Jared Grubb

unread,
Jul 28, 2015, 11:03:31 PM7/28/15
to ISO C++ Standard - Future Proposals, myri...@gmail.com
+1000. This inconsistency has always annoyed me as well.

On Monday, July 27, 2015 at 3:02:06 PM UTC-7, Myriachan wrote:
To fix a minor annoyance for a long time, I think that the initializer list following a constructor prototype should allow a trailing comma with nothing after it.  This also makes initializer lists consistent with enums (C++11) and aggregate initializers (C++03?).  The purpose is to assist when editing, and helping when using "svn blame" or the equivalent for your version control.

Yes, I have seen the workaround of putting commas on the next line, but this doesn't match some coding styles.

class dword_table
{
public:
    dword_table(std::size_t count)
    try
    :   m_array(new std::uint32_t[count]),
        m_count(count),
    {
    }
    catch (std::bad_alloc)
    {
        std::fprintf(stderr, "out of memory allocating %zu dwords", count);
        throw;
    }
    ...
};

Melissa

dgutson .

unread,
Jul 28, 2015, 11:31:28 PM7/28/15
to std-proposals

I couldn't strongly argue your point, but to mention 2 things:
1) frequency of change (base-specifier list versus members initializer list)
2) usual layout:allowing a trailing comma is better suited for things that are usually vertically listed (such as enums and members initialization) rather than horizontally listed (base classes list, function arguments, template arguments). Let's keep in mind that VCS are line-oriented.

Roland Bock

unread,
Jul 29, 2015, 2:25:24 AM7/29/15
to std-pr...@isocpp.org
On 2015-07-29 05:03, Jared Grubb wrote:
+1000. This inconsistency has always annoyed me as well.
same here, both in manual code maintenance and with code generators

--

Ville Voutilainen

unread,
Jul 29, 2015, 5:08:19 AM7/29/15
to ISO C++ Standard - Future Proposals
On 29 July 2015 at 05:03, David Krauss <pot...@gmail.com> wrote:
> Compilers are labor-saving devices. Implementation work is well spent if it saves time for users. What we have in this thread is customers agreeing that they’re wasting time because this C++ grammar quirk chokes other tools in the chain. The customer is usually right, unless there’s an argument that the feature could be dangerous.

Dearest Customers,

I have implemented the proposed change for gcc, see
https://github.com/villevoutilainen/gcc/commit/3e7dc8cc67ef5a3c302ff15c90b0c7cbc56760e9
if you want to play with it.

Should some of you write a proposal for this change, and should the
committee accept the
change, I would be more than happy to submit this patch for inclusion into gcc.

Disclaimer: Kindly do not take this as endorsement of the feature. I
remain unconvinced
of the merits of the proposed feature, although I have no plans to
expend energy to
sink it if the committee is willing to adopt it.

P.S. For people concerned about my "warding off work", feel free to
have a tasty stew
of crow.

Arthur Tchaikovsky

unread,
Jul 29, 2015, 6:34:28 AM7/29/15
to ISO C++ Standard - Future Proposals, ville.vo...@gmail.com
Hi Ville,
So in the same spirit, why can't we have (in the sake of consistency) similar construct allowed:

class X: public: A,B,C; protected D,E,F
{
public:
A a;
B b;
C c;
protected:
D d;
E e;
F f;
};

The point ^^^ here is that we are inheriting in similar manner to classifying access level of members of a class, that is, we are stating only once the desired inheritance level, not every time as we are obliged to do now, unless we inheriting privately.
This change is:
a) Non breaking existing code
b) Makes class declaration more uniform

Ville Voutilainen

unread,
Jul 29, 2015, 8:43:19 AM7/29/15
to ISO C++ Standard - Future Proposals
On 29 July 2015 at 13:34, Arthur Tchaikovsky <atch...@gmail.com> wrote:
> Hi Ville,
> So in the same spirit, why can't we have (in the sake of consistency)
> similar construct allowed:
> class X: public: A,B,C; protected D,E,F

That is not "in the same spirit", and I fail to see the consistency argument.
That idea has very little to do with a trailing comma in any list, and
its motivation
would seem completely different.

> {
> public:
> A a;
> B b;
> C c;
> protected:
> D d;
> E e;
> F f;
> };
>
> The point ^^^ here is that we are inheriting in similar manner to
> classifying access level of members of a class, that is, we are stating only
> once the desired inheritance level, not every time as we are obliged to do
> now, unless we inheriting privately.
> This change is:
> a) Non breaking existing code
> b) Makes class declaration more uniform


But as has been mentioned, multiple base classes are much rarer than multiple
non-static data members, so the motivation for such a thing seems weak.

Arthur Tchaikovsky

unread,
Jul 29, 2015, 10:06:11 AM7/29/15
to ISO C++ Standard - Future Proposals, ville.vo...@gmail.com
It is in the same spirit that is: *make things uniform*.
The consistency argument is:
if in declaration of a class we can:


public:
A a;
B b;

Why can't we do the same whilst declaring what classes we are inheriting from:
class X: public: A,B,C;<-- here A,B,C would be publicly inherited
{
};

Matthew Woehlke

unread,
Jul 29, 2015, 11:42:34 AM7/29/15
to std-pr...@isocpp.org
On 2015-07-28 17:37, Ville Voutilainen wrote:
> On 28 July 2015 at 19:42, Thiago Macieira wrote:
>> Besides, comma at the end of enums is permitted. Why not at the end of other
>> lists?
>
> If we want to allow a trailing comma in a ctor-initializer list, what about the
> base-specifier list?

Again, I'd consider this a harmless addition. (So, "yes", but a weak "yes".)

--
Matthew

Ville Voutilainen

unread,
Jul 29, 2015, 11:45:53 AM7/29/15
to ISO C++ Standard - Future Proposals
Well, let's see what people end up proposing. I have implementation experience
for the mem-initializer-list case, but I have no time to play with
other hypothetical
changes. I think the base-specifier list has much weaker motivation than the
mem-initializer-list.

Matthew Woehlke

unread,
Jul 29, 2015, 11:51:31 AM7/29/15
to std-pr...@isocpp.org
On 2015-07-28 22:03, David Krauss wrote:
> If you were to write the initializations as assignments in the
> function body, you wouldn’t even think of running the statements
> together on one line.

Devil's advocate: I've not only thought about it, I've done so :-).
(Usually the assignments are related, e.g. elements in an array.)

Example:

this->bg [0] = 128; this->bg [1] = 128; this->bg [2] = 128;
this->fg1[0] = 255; this->fg1[1] = 255; this->fg1[2] = 0;
this->fg2[0] = 64; this->fg2[1] = 64; this->fg2[2] = 255;

I've also written stuff like:

this->a = this->b = this->c = value;

In fairness, neither are *common*, but they do happen :-).

> Mem-initializers [... are] like enumerator declarations and aggregate
> initializers, and unlike function arguments. Base classes also often
> get listed line by line, but multiple inheritance is uncommon.

Actually, in all three cases (okay, less sure about one-per-line base
classes than the other two) I've written both run-on and one-per-line.
Likewise member initializers. And when I say "both", I even mean within
the same code base (i.e. following same coding style). Frequently the
choice depends on the number and/or individual length of the items being
written.

--
Matthew

Matthew Woehlke

unread,
Jul 29, 2015, 11:55:07 AM7/29/15
to std-pr...@isocpp.org
Agreed; what I mean is I don't feel a particular need to propose it, but
don't have any philosophical objection to it.

--
Matthew

Myriachan

unread,
Jul 29, 2015, 8:11:57 PM7/29/15
to ISO C++ Standard - Future Proposals, ville.vo...@gmail.com

Making the base class list behave this way would break existing code.  For example:

struct Base1 { ... };
struct Base2
{
   
virtual ~Base2() { }
   
void DoStuff() { ... }
};
struct Derived : private Base1, Base2 { ... };

int main()
{
   
Base2 *meow = new Derived();
    meow
->DoStuff();
   
delete meow;
   
return 0;
}


I noticed the semicolon in Arthur's example; using that to distinguish the old way versus the new way resolves this problem, but making the semicolon have that sort of meaning feels crazy.

Melissa

Ville Voutilainen

unread,
Jul 29, 2015, 8:52:57 PM7/29/15
to ISO C++ Standard - Future Proposals
On 30 July 2015 at 03:11, Myriachan <myri...@gmail.com> wrote:
>> Well, let's see what people end up proposing. I have implementation
>> experience
>> for the mem-initializer-list case, but I have no time to play with
>> other hypothetical
>> changes. I think the base-specifier list has much weaker motivation than
>> the
>> mem-initializer-list.
> Making the base class list behave this way would break existing code. For
> example:
> struct Derived : private Base1, Base2 { ... };

But I wasn't talking about any such change, I know it's a breaking
change. What I referred
to was allowing a trailing comma in the base-specifier, thus:
struct Derived : private Base1, Base2, { ... };
quite like allowing it in a mem-initializer-list, but as I said, the
motivation for something
like that is much weaker.

David Krauss

unread,
Jul 30, 2015, 2:57:51 AM7/30/15
to std-pr...@isocpp.org

On 2015–07–29, at 5:08 PM, Ville Voutilainen <ville.vo...@gmail.com> wrote:

P.S. For people concerned about my "warding off work", feel free to
have a tasty stew
of crow.

Anyone who ever said that must be nuts. You seem to be on a roll with GCC lately.

If nobody else steps up, I’ll write the proposal. I’ll be sure to include some pictures of diffs.

Base specifiers don’t seem to be part of this package.

Greg Marr

unread,
Jul 30, 2015, 4:01:17 PM7/30/15
to ISO C++ Standard - Future Proposals, ville.vo...@gmail.com, myri...@gmail.com
On Wednesday, July 29, 2015 at 8:11:57 PM UTC-4, Myriachan wrote:
Making the base class list behave this way would break existing code.  For example:

struct Base1 { ... };
struct Base2
{
   
virtual ~Base2() { }
   
void DoStuff() { ... }
};
struct Derived : private Base1, Base2 { ... };

int main()
{
   
Base2 *meow = new Derived();
    meow
->DoStuff();
   
delete meow;
   
return 0;
}


I noticed the semicolon in Arthur's example; using that to distinguish the old way versus the new way resolves this problem, but making the semicolon have that sort of meaning feels crazy.

There was also a colon after the public

Myriachan

unread,
Jul 30, 2015, 7:45:58 PM7/30/15
to ISO C++ Standard - Future Proposals, pot...@gmail.com
On Wednesday, July 29, 2015 at 11:57:51 PM UTC-7, David Krauss wrote:

Anyone who ever said that must be nuts. You seem to be on a roll with GCC lately.

If nobody else steps up, I’ll write the proposal. I’ll be sure to include some pictures of diffs.

Base specifiers don’t seem to be part of this package.


I'd be willing to write it if I knew the right format, and where to find diffs of this type without searching forever in open-source projects =^-^=

Melissa

Richard Smith

unread,
Jul 30, 2015, 8:08:08 PM7/30/15
to std-pr...@isocpp.org
FWIW, I'd be opposed to this proposal if it suggests changing mem-initializers but not base-specifiers. If we want to allow optional commas after comma-separated lists, we should allow that consistently, especially between constructs that deliberately have similar grammar productions.

(Take a look at the implementation of any class that implements multiple MS COM interfaces for a motivating example for allowing trailing commas in base specifiers.)

Arthur O'Dwyer

unread,
Jul 30, 2015, 9:09:23 PM7/30/15
to std-pr...@isocpp.org
Richard's comment seems eminently reasonable to me.
https://github.com/cplusplus/draft/compare/master...Quuxplusone:mem_initializer_list_comma

I wish it were easy to come up with a black-and-white separation between these kinds of changes and the slippery slope that leads to flamewars over whether to permit

    using id = std::tuple<
        int,
        double,  // trailing comma is currently disallowed here
    >;

    auto f = [
        alpha=std::move(alpha),
        beta=std::move(beta),  // and here
    ](
        int x,
        int y,  // and here
    ) {
    };
    auto x = f(
        1,
        2,  // and here
    );

In practice the rule seems to be, "Wait for consensus to form in favor of trailing-comma in a specific construct, and then add just that one trailing-comma production to the grammar."  But actually I can't think of any real reason for anyone to object to trailing-comma in all of the above cases.

Let's not start a flamewar right now, but just as a recreational puzzle, can anyone come up with a situation in which C++ currently uses comma as a separator (not the comma-operator) and where permitting "trailing comma" in that situation would lead to grammatical ambiguity?

–Arthur



--

---
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/I8N_75J9ZB8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.

Patrice Roy

unread,
Jul 30, 2015, 9:44:16 PM7/30/15
to std-pr...@isocpp.org
I can understand the usefulness of trailing commas to simplify management tasks. It is an illogical and weird thing. I won't oppose it, but I really hope those who champion it really think it's the best solution to the problems they're having. From the outside (not suffering from the basic problem), it really seems like an awkward thing to accept. I'd be much more confortable if we looked for something that makes more sense, even if the pragmatic argument isn't of the unreasonable kind. It makes me feel uncomfortable to push for something that, essentially, makes no sense in order to alleviate what (so far) seems like tooling issues...

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.

David Krauss

unread,
Jul 30, 2015, 11:14:21 PM7/30/15
to std-pr...@isocpp.org
On 2015–07–31, at 9:09 AM, Arthur O'Dwyer <arthur....@gmail.com> wrote:

In practice the rule seems to be, "Wait for consensus to form in favor of trailing-comma in a specific construct, and then add just that one trailing-comma production to the grammar."  But actually I can't think of any real reason for anyone to object to trailing-comma in all of the above cases.

You’re already implicitly acknowledging it, but the only alternative is to wait for consensus to form in favor of adding trailing-comma in all contexts.

Maybe taking the one case is a half-measure, but it doesn’t impede future progress. What will be the half-measure’s ultimate effect toward allowing all the cases? The demand will increase (folks come to expect more convenience) or decrease (the actual need has been satisfied). Either way is fine in the end, but if we take the smaller proposal as a hostage to negotiate for something bigger, the likely outcome is nothing, ever.

The slippery slope doesn’t end with commas, either. How about lists of Boolean conditions; should trailing && and || operators get ignored too? It would just be ordinary postfix expression syntax.

Sure, there are plenty of cases where template or function arguments get listed line by line, but those tend to verge on either EDSL territory or language abuse. Likewise with any kind of statement that runs for many lines: If you’re doing it all the time, you’re already accepting a loss of readability. It’s far less common than merely having several nonstatic members and several constructors that initialize them.

As for the cases with declarations (parameter lists and capture lists), the better style is to write a one-line comment for each name, and put the list below that.

Let's not start a flamewar right now, but just as a recreational puzzle, can anyone come up with a situation in which C++ currently uses comma as a separator (not the comma-operator) and where permitting "trailing comma" in that situation would lead to grammatical ambiguity?

I don’t suppose the preprocessor counts :v) .

Magnus Fromreide

unread,
Jul 31, 2015, 1:11:56 AM7/31/15
to std-pr...@isocpp.org
On Thu, Jul 30, 2015 at 06:09:21PM -0700, Arthur O'Dwyer wrote:
> Richard's comment seems eminently reasonable to me.
> https://github.com/cplusplus/draft/compare/master...Quuxplusone:mem_initializer_list_comma
>
> I wish it were easy to come up with a black-and-white separation between
> these kinds of changes and the slippery slope that leads to flamewars over
> whether to permit
>
> auto x = f(
> 1,
> 2, // and here
> );
>
> In practice the rule seems to be, "Wait for consensus to form in favor of
> trailing-comma in a specific construct, and then add just that one
> trailing-comma production to the grammar." But actually I can't think of
> any real reason for anyone to object to trailing-comma in all of the above
> cases.
>
> Let's not start a flamewar right now, but *just as a recreational puzzle,*
> can anyone come up with a situation in which C++ currently uses comma as a
> separator (not the comma-operator) and where permitting "trailing comma" in
> that situation would lead to grammatical ambiguity?

In another thread there was a suggestion that

f(a, , c) should use the default argument for the second parameter to f.

If we at the same time says that trailing commas in functions might be
ignored then that would make the overload resolution rules more complicated.

Consider:

int g(short a, int = 0);
int g(long a);

...

int x = g(17,);

Today g(17) is ambiguous.
With the empty parameter means default rule g(17,) would be well defined.
With the ignore comma rule g(17,) would be ambigous.

In conclusion I think ignored commas in function arguments prevents other
possibilities.

/MF

Miro Knejp

unread,
Jul 31, 2015, 12:01:02 PM7/31/15
to std-pr...@isocpp.org
g(17, default)
Problem solved?
This proposal isn't about ignoring arbitrary commas, only the last one
in a comma-separated list where the commas are not the comma-operator.
The suggestion you're quoting here is in my oppinion waaaaay too subtle
and is very prone to accidental copy/paste errors.
Reply all
Reply to author
Forward
0 new messages