[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<--
- [lmi] Unexpected clang error message,
Greg Chicares <=