lmi
[Top][All Lists]
Advanced

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

[lmi] Unexpected clang error message


From: Greg Chicares
Subject: [lmi] Unexpected clang error message
Date: Tue, 2 Aug 2022 20:19:33 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0

I expect a particular clang error message, but get a different one,
when I compile the code below in these two different ways, with
macro "NONEMPTY" variously defined or undefined:

$clang++ -DNONEMPTY -fsyntax-only -Wall -std=c++20 eraseme.cpp 2>&1 |grep 
'error:'
eraseme.cpp:28:7: error: call to constructor of 'X' is ambiguous
eraseme.cpp:29:7: error: call to constructor of 'X' is ambiguous
eraseme.cpp:30:7: error: use of overloaded operator '=' is ambiguous (with 
operand types 'X' and 'ambiguator<X>')

In the "defined" case above, those are the errors I expect.

$clang++ -UNONEMPTY -fsyntax-only -Wall -std=c++20 eraseme.cpp 2>&1 |grep 
'error:'
eraseme.cpp:28:10: error: excess elements in struct initializer
eraseme.cpp:29:10: error: excess elements in struct initializer
eraseme.cpp:30:7: error: use of overloaded operator '=' is ambiguous (with 
operand types 'X' and 'ambiguator<X>')

In the "undefined" case, however, instead of the "...is ambiguous"
warning that I expect, clang complains of excess initializers.
What does that even mean here? A few lines above, this:
  X s {q};
was accepted, so 'X' must have a copy ctor in this case
(-UNONEMPTY => NONEMPTY undefined => "empty" class body). And I
did manage to instantiate
  ambiguator<X> ax;
but
  X y {ax};
is rejected. How can "X y {ax};" have excess initializer elements
when "X s {q};" has an acceptable number, since both initializers
have exactly one element AFAICS?

The gcc error messages are similar--in the -UNONEMPTY case:
  eraseme.cpp:28:25: error: too many initializers for ‘X’
     28 |     X x {ambiguator<X>{}};
        |                         ^
  eraseme.cpp:29:12: error: too many initializers for ‘X’
     29 |     X y {ax};
        |            ^

At first, that message for line 28 made me think I violated the
"{}" syntax, but to test that idea I added line 29, where I don't
see how I could possibly have gotten the syntax wrong.

Here's 'eraseme.cpp':

--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--
template<typename T>
struct ambiguator
{
    operator T const&();
    operator T&&();
};

struct X
{
#if NONEMPTY
    X()                    = default;
    ~X()                   = default;
    X(X const&)            = default;
    X(X&&)                 = default;
    X& operator=(X const&) = default;
    X& operator=(X&&)      = default;
#endif // NONEMPTY
};

int main()
{
    X q;
    X r {};
    X s {q};

    ambiguator<X> ax;

    X x {ambiguator<X>{}}; // line 28
    X y {ax};              // line 29
    x = ambiguator<X>{};   // line 30

    return 0;
}
--8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<--


reply via email to

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