public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor
@ 2022-12-03 16:48 nruslan_devel at yahoo dot com
  2022-12-03 17:01 ` [Bug c++/107958] " pinskia at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: nruslan_devel at yahoo dot com @ 2022-12-03 16:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

            Bug ID: 107958
           Summary: Ambiguity with uniform initialization in overloaded
                    operator and explicit constructor
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nruslan_devel at yahoo dot com
  Target Milestone: ---

Suppose we have the following example with a class that has to keep two
pointers. (I actually encountered this error with a more complex example, but
this one is just for illustration.) The problem arises when I attempt to use
the assignment operator and curly braces.

If I understand correctly, two possibilities exist when passing curly braces:

1. Use the overloaded operator= (implicitly convert curly braces to a pair). In
this particular example, we could have probably used make_pair but I
deliberately put curly braces to show how this error is triggered.

2. Use the constructor to create a new PairPtr instance and then copy it to the
old object through operator=

Both clang and gcc complain unless I mark the corresponding constructor as
'explicit'. To avoid the ambiguity with the second case, I mark the
corresponding constructor as 'explicit' and expect that the overloaded
operator= to be used. That seems to work with clang/llvm but not with gcc (see
the error below).

#include <iostream>
#include <utility>

struct PairPtr {

    PairPtr() {}

    PairPtr(const PairPtr &s) {
        a = s.a;
        b = s.b;
    }

    explicit PairPtr(int *_a, int *_b) {
        a = _a;
        b = _b;
    }

    PairPtr& operator=(const PairPtr &s) {
        a = s.a;
        b = s.b;
        return *this;
    }

    PairPtr& operator=(const std::pair<int *, int *>& pair) {
        a = pair.first;
        b = pair.second;
        return *this;
    }

    int *a;
    int *b;
};

void func(int *a, int *b)
{
    PairPtr p;

    p = { a, b };
}


Error (note that clang/llvm can compile the above code successfully!):

Note that 'explicit' for the constructor fixes the problem for clang/llvm but
does not fix the problem for gcc.

2.cpp: In function ‘void func(int*, int*)’:
2.cpp:38:20: error: ambiguous overload for ‘operator=’ (operand types are
‘PairPtr’ and ‘<brace-enclosed initializer list>’)
   38 |         p = { a, b };
      |                    ^
2.cpp:18:18: note: candidate: ‘PairPtr& PairPtr::operator=(const PairPtr&)’
   18 |         PairPtr& operator=(const PairPtr &s) {
      |                  ^~~~~~~~
2.cpp:24:18: note: candidate: ‘PairPtr& PairPtr::operator=(const
std::pair<int*, int*>&)’
   24 |         PairPtr& operator=(const std::pair<int *, int *>& pair) {
      |

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
@ 2022-12-03 17:01 ` pinskia at gcc dot gnu.org
  2022-12-03 17:05 ` pinskia at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 17:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note MSVC (with /std:c++latest) also rejects the source that is in comment #0
for the same reason as GCC:

<source>(39): error C2593: 'operator =' is ambiguous
<source>(25): note: could be 'PairPtr &PairPtr::operator =(const std::pair<int
*,int *> &)'
<source>(19): note: or       'PairPtr &PairPtr::operator =(const PairPtr &)'
<source>(39): note: while trying to match the argument list '(PairPtr,
initializer list)'

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
  2022-12-03 17:01 ` [Bug c++/107958] " pinskia at gcc dot gnu.org
@ 2022-12-03 17:05 ` pinskia at gcc dot gnu.org
  2022-12-03 17:11 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 17:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=85577

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Maybe related to C++ defect report 2137 (see PR 85577 for other details on
that) which GCC is known to implement but clang does not:

https://cplusplus.github.io/CWG/issues/2137.html

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
  2022-12-03 17:01 ` [Bug c++/107958] " pinskia at gcc dot gnu.org
  2022-12-03 17:05 ` pinskia at gcc dot gnu.org
@ 2022-12-03 17:11 ` pinskia at gcc dot gnu.org
  2022-12-03 18:12 ` pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 17:11 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Obvious workaround is to do:
    p = PairPtr{ a, b };

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (2 preceding siblings ...)
  2022-12-03 17:11 ` pinskia at gcc dot gnu.org
@ 2022-12-03 18:12 ` pinskia at gcc dot gnu.org
  2022-12-03 18:22 ` pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 18:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I think GCC and MSVC are correct here:
[over.match.list]/16.3.1.7
. In copy-listinitialization, if an explicit constructor is chosen, the
initialization is ill-formed. [ Note: This differs from
other situations (16.3.1.3, 16.3.1.4), where only converting constructors are
considered for copy-initialization.
This restriction only applies if this initialization is part of the final
result of overload resolution. — end note ]


Even though the note is techincally not part of the standard, it describes why
clang is wrong here. That is the explicit constructors are used too to figure
out the overload and only if there was no ambiguous, it would be considered as
ill-formed.

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (3 preceding siblings ...)
  2022-12-03 18:12 ` pinskia at gcc dot gnu.org
@ 2022-12-03 18:22 ` pinskia at gcc dot gnu.org
  2022-12-03 18:46 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 18:22 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Actually I think there is some disagreement if dcl.init.list/3.4 (that is
aggregate initialization) applies ...

Because if I make the two fields private, then gcc (and MSVC) accepts it ...

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (4 preceding siblings ...)
  2022-12-03 18:22 ` pinskia at gcc dot gnu.org
@ 2022-12-03 18:46 ` pinskia at gcc dot gnu.org
  2022-12-03 18:49 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 18:46 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #4)
> I think GCC and MSVC are correct here:
> [over.match.list]/16.3.1.7
> . In copy-listinitialization, if an explicit constructor is chosen, the
> initialization is ill-formed. [ Note: This differs from
> other situations (16.3.1.3, 16.3.1.4), where only converting constructors
> are considered for copy-initialization.
> This restriction only applies if this initialization is part of the final
> result of overload resolution. — end note ]
> 
> 
> Even though the note is techincally not part of the standard, it describes
> why clang is wrong here. That is the explicit constructors are used too to
> figure out the overload and only if there was no ambiguous, it would be
> considered as ill-formed.

Also see clang bug https://github.com/llvm/llvm-project/issues/28016

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (5 preceding siblings ...)
  2022-12-03 18:46 ` pinskia at gcc dot gnu.org
@ 2022-12-03 18:49 ` pinskia at gcc dot gnu.org
  2022-12-03 18:50 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 18:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED
           See Also|                            |https://github.com/llvm/llv
                   |                            |m-project/issues/28016

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Yes https://github.com/llvm/llvm-project/issues/28016 is the clang bug which
shows GCC is correct.  This is also
https://www.open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1228 .

So clang is wrong in accepting the code as not ambiguous .

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (6 preceding siblings ...)
  2022-12-03 18:49 ` pinskia at gcc dot gnu.org
@ 2022-12-03 18:50 ` pinskia at gcc dot gnu.org
  2022-12-04  4:19 ` nruslan_devel at yahoo dot com
  2022-12-04  4:39 ` nruslan_devel at yahoo dot com
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-03 18:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |DUPLICATE

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup of bug 60027.

*** This bug has been marked as a duplicate of bug 60027 ***

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (7 preceding siblings ...)
  2022-12-03 18:50 ` pinskia at gcc dot gnu.org
@ 2022-12-04  4:19 ` nruslan_devel at yahoo dot com
  2022-12-04  4:39 ` nruslan_devel at yahoo dot com
  9 siblings, 0 replies; 11+ messages in thread
From: nruslan_devel at yahoo dot com @ 2022-12-04  4:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #9 from Ruslan Nikolaev <nruslan_devel at yahoo dot com> ---
Interestingly, if I change the code a little bit and have a pair in the
constructor rather than two arguments, gcc seems to compile the code:

#include <iostream>
#include <utility>

struct PairPtr {

    PairPtr() {}

    PairPtr(const PairPtr &s) {
        a = s.a;
        b = s.b;
    }

    explicit PairPtr(const std::pair<int *, int *>& pair) {
        a = pair.first;
        b = pair.second;
    }

    PairPtr& operator=(const PairPtr &s) {
        a = s.a;
        b = s.b;
        return *this;
    }

    PairPtr& operator=(const std::pair<int *, int *>& pair) {
        a = pair.first;
        b = pair.second;
        return *this;
    }

private:
    int *a;
    int *b;
};

void func(int *a, int *b)
{
    PairPtr p({a,b}); // works

    p = { a, b }; // also works
}

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

* [Bug c++/107958] Ambiguity with uniform initialization in overloaded operator and explicit constructor
  2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
                   ` (8 preceding siblings ...)
  2022-12-04  4:19 ` nruslan_devel at yahoo dot com
@ 2022-12-04  4:39 ` nruslan_devel at yahoo dot com
  9 siblings, 0 replies; 11+ messages in thread
From: nruslan_devel at yahoo dot com @ 2022-12-04  4:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107958

--- Comment #10 from Ruslan Nikolaev <nruslan_devel at yahoo dot com> ---
The latter example seems to work well for both gcc and clang. The behavior is
also consistent for both explicit and implicit constructors.

Thank you for clarifying that it was not a bug!

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

end of thread, other threads:[~2022-12-04  4:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-03 16:48 [Bug c++/107958] New: Ambiguity with uniform initialization in overloaded operator and explicit constructor nruslan_devel at yahoo dot com
2022-12-03 17:01 ` [Bug c++/107958] " pinskia at gcc dot gnu.org
2022-12-03 17:05 ` pinskia at gcc dot gnu.org
2022-12-03 17:11 ` pinskia at gcc dot gnu.org
2022-12-03 18:12 ` pinskia at gcc dot gnu.org
2022-12-03 18:22 ` pinskia at gcc dot gnu.org
2022-12-03 18:46 ` pinskia at gcc dot gnu.org
2022-12-03 18:49 ` pinskia at gcc dot gnu.org
2022-12-03 18:50 ` pinskia at gcc dot gnu.org
2022-12-04  4:19 ` nruslan_devel at yahoo dot com
2022-12-04  4:39 ` nruslan_devel at yahoo dot com

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).