public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Lenient overhead resolutions and where to find them in the manual
@ 2024-01-29 18:17 Martin Licht
  2024-01-29 18:24 ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Licht @ 2024-01-29 18:17 UTC (permalink / raw)
  To: gcc

GCC seems to have a non-standard lenient C++ overload resolution that is 
not documented (or easy to find in the manual).

The following C++ code compiles with GCC. However, it produces a warning 
about an ambiguous overload that apparently is not acceptable by the 
standard. Clang and MVSC simply reject the code because of the ambiguous 
overload.

```
// reduced example
#include <iostream>
using namespace std;
struct A{};
struct B: public A {};
struct C{};
struct D{ D() = default; D(const C&){}; };

void p( A&, const C& ){ cout << "AC\n"; };
void p( B&, const D& ){ cout << "BD\n"; };

int main() {
     B b; C c;
     p(b,c); // ambiguous call
     return 0;
}
```

GCC detects ambiguity in which `p` to choose: either cast from derived 
class B& to base class A& or construct D from C.

```
$ g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:51:10: warning: ISO C++ says that these are ambiguous, even 
though the worst conversion for the first is better than the worst 
conversion for the second:
    51 |         p(b,c);
       |         ~^~~~~
test.cpp:12:6: note: candidate 1: ‘void p(A&, const C&)’
    12 | void p( A&, const C& ){ cout << "AC\n"; };
       |      ^
test.cpp:15:6: note: candidate 2: ‘void p(B&, const D&)’
    15 | void p( B&, const D& ){ cout << "BD\n"; };
       |      ^
```

With `-pedantic` it does not compile anymore. I subjectively agree with 
GCC that the first choice is better than the second. But not everyone 
may do so. Is there a documentation of all these deviations from the 
standard?


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Lenient overhead resolutions and where to find them in the manual
  2024-01-29 18:17 Lenient overhead resolutions and where to find them in the manual Martin Licht
@ 2024-01-29 18:24 ` Jonathan Wakely
  2024-01-29 18:24   ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2024-01-29 18:24 UTC (permalink / raw)
  To: Martin Licht; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 2028 bytes --]

On Mon, 29 Jan 2024, 18:17 Martin Licht via Gcc, <gcc@gcc.gnu.org> wrote:

> GCC seems to have a non-standard lenient C++ overload resolution that is
> not documented (or easy to find in the manual).
>
> The following C++ code compiles with GCC. However, it produces a warning
> about an ambiguous overload that apparently is not acceptable by the
> standard. Clang and MVSC simply reject the code because of the ambiguous
> overload.
>
> ```
> // reduced example
> #include <iostream>
> using namespace std;
> struct A{};
> struct B: public A {};
> struct C{};
> struct D{ D() = default; D(const C&){}; };
>
> void p( A&, const C& ){ cout << "AC\n"; };
> void p( B&, const D& ){ cout << "BD\n"; };
>
> int main() {
>      B b; C c;
>      p(b,c); // ambiguous call
>      return 0;
> }
> ```
>
> GCC detects ambiguity in which `p` to choose: either cast from derived
> class B& to base class A& or construct D from C.
>
> ```
> $ g++ test.cpp
> test.cpp: In function ‘int main()’:
> test.cpp:51:10: warning: ISO C++ says that these are ambiguous, even
> though the worst conversion for the first is better than the worst
> conversion for the second:
>     51 |         p(b,c);
>        |         ~^~~~~
> test.cpp:12:6: note: candidate 1: ‘void p(A&, const C&)’
>     12 | void p( A&, const C& ){ cout << "AC\n"; };
>        |      ^
> test.cpp:15:6: note: candidate 2: ‘void p(B&, const D&)’
>     15 | void p( B&, const D& ){ cout << "BD\n"; };
>        |      ^
> ```
>
> With `-pedantic` it does not compile anymore. I subjectively agree with
> GCC that the first choice is better than the second. But not everyone
> may do so. Is there a documentation of all these deviations from the
> standard?
>


The standard says this is ill-formed and requires a diagnostic, and gcc
gives you a diagnostic. So it's not strictly-speaking a deviation from the
standard.

I don't think there are docs for this or for other similar "pedwarn"
extensions.



>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Lenient overhead resolutions and where to find them in the manual
  2024-01-29 18:24 ` Jonathan Wakely
@ 2024-01-29 18:24   ` Jonathan Wakely
  0 siblings, 0 replies; 3+ messages in thread
From: Jonathan Wakely @ 2024-01-29 18:24 UTC (permalink / raw)
  To: Martin Licht; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 2247 bytes --]

On Mon, 29 Jan 2024, 18:24 Jonathan Wakely, <jwakely.gcc@gmail.com> wrote:

>
>
> On Mon, 29 Jan 2024, 18:17 Martin Licht via Gcc, <gcc@gcc.gnu.org> wrote:
>
>> GCC seems to have a non-standard lenient C++ overload resolution that is
>> not documented (or easy to find in the manual).
>>
>> The following C++ code compiles with GCC. However, it produces a warning
>> about an ambiguous overload that apparently is not acceptable by the
>> standard. Clang and MVSC simply reject the code because of the ambiguous
>> overload.
>>
>> ```
>> // reduced example
>> #include <iostream>
>> using namespace std;
>> struct A{};
>> struct B: public A {};
>> struct C{};
>> struct D{ D() = default; D(const C&){}; };
>>
>> void p( A&, const C& ){ cout << "AC\n"; };
>> void p( B&, const D& ){ cout << "BD\n"; };
>>
>> int main() {
>>      B b; C c;
>>      p(b,c); // ambiguous call
>>      return 0;
>> }
>> ```
>>
>> GCC detects ambiguity in which `p` to choose: either cast from derived
>> class B& to base class A& or construct D from C.
>>
>> ```
>> $ g++ test.cpp
>> test.cpp: In function ‘int main()’:
>> test.cpp:51:10: warning: ISO C++ says that these are ambiguous, even
>> though the worst conversion for the first is better than the worst
>> conversion for the second:
>>     51 |         p(b,c);
>>        |         ~^~~~~
>> test.cpp:12:6: note: candidate 1: ‘void p(A&, const C&)’
>>     12 | void p( A&, const C& ){ cout << "AC\n"; };
>>        |      ^
>> test.cpp:15:6: note: candidate 2: ‘void p(B&, const D&)’
>>     15 | void p( B&, const D& ){ cout << "BD\n"; };
>>        |      ^
>> ```
>>
>> With `-pedantic` it does not compile anymore. I subjectively agree with
>> GCC that the first choice is better than the second. But not everyone
>> may do so. Is there a documentation of all these deviations from the
>> standard?
>>
>
>
> The standard says this is ill-formed and requires a diagnostic, and gcc
> gives you a diagnostic. So it's not strictly-speaking a deviation from the
> standard.
>
> I don't think there are docs for this or for other similar "pedwarn"
> extensions.
>

You can find them all by grepping the sources for pedwarn though.

>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-29 18:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-29 18:17 Lenient overhead resolutions and where to find them in the manual Martin Licht
2024-01-29 18:24 ` Jonathan Wakely
2024-01-29 18:24   ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).