lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Unexpected clang error message


From: Vadim Zeitlin
Subject: Re: [lmi] Unexpected clang error message
Date: Wed, 3 Aug 2022 14:23:12 +0200

On Tue, 2 Aug 2022 20:19:33 +0000 Greg Chicares <gchicares@sbcglobal.net> wrote:

GC> I expect a particular clang error message, but get a different one,
GC> when I compile the code below in these two different ways, with
GC> macro "NONEMPTY" variously defined or undefined:
GC> 
GC> $clang++ -DNONEMPTY -fsyntax-only -Wall -std=c++20 eraseme.cpp 2>&1 |grep 
'error:'
GC> eraseme.cpp:28:7: error: call to constructor of 'X' is ambiguous

 For me, this is indeed expected because you define a ctor, and even
multiple ctors, and the compiler can't choose between them.

GC> $clang++ -UNONEMPTY -fsyntax-only -Wall -std=c++20 eraseme.cpp 2>&1 |grep 
'error:'
GC> eraseme.cpp:28:10: error: excess elements in struct initializer

 For me, this is expected too because you don't define any ctors and hence
the struct is an aggregate and the initialization syntax used becomes
aggregate initialization. And, of course, it's a very specific kind of an
aggregate -- a degenerate, empty one. So any initializer specified here is
an excessive one.

GC> but
GC>   X y {ax};
GC> is rejected. How can "X y {ax};" have excess initializer elements
GC> when "X s {q};" has an acceptable number, since both initializers
GC> have exactly one element AFAICS?

 This is indeed a nice quiz question (but then making quiz questions about
C++ initialization rules is too easy). I admit I could have answered it
wrongly myself but, of course, knowing the result it's easy to provide the
rationale: the latter example works because even though X is an aggregate,
it still has the copy ctor and it's considered before the aggregate
initialization (and it has to be, of course, because otherwise you'd never
be able to use copy ctors with the aggregates).

 So, in -UNONEMPTY case, the rule for brace initialization can be
summarized as:

- If it looks like a copy (or move) ctor, use this one.
- Otherwise use aggregate initialization.

 While in -DNONEMPTY case, it's just to use whichever ctor matches because
aggregate initialization is inhibited by the explicit ctor declaration.

 Does this help answering your question or am I missing something again?
VZ

Attachment: pgpDQzS8zJzfR.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]