[RFA 1/8] Add gdb_ref_ptr.h

Pedro Alves palves@redhat.com
Fri Dec 2 23:45:00 GMT 2016

On 12/02/2016 07:52 PM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
> Pedro> I think gcc will list you all candidates, mentioning why each one
> Pedro> can't work.  I.e., it likely tells you more further below?
> Yeah, it does, I missed that.

Ah, trying locally and getting at the compile log helped.  The overload
we'd expect to work, doesn't:

..../src/gdb/solib-darwin.c: In function ‘void darwin_solib_get_all_image_info_addr_at_init(darwin_info*)’:
..../src/gdb/solib-darwin.c:467:16: error: no match for ‘operator!=’ (operand types are ‘gdb_bfd_ref_ptr {aka gdb::ref_ptr<bfd, gdb_bfd_ref_policy>}’ and ‘long int’)
   if (dyld_bfd != NULL)
..../src/gdb/common/gdb_ref_ptr.h:212:13: note: candidate: template<class T, class POLICY> bool gdb::operator!=(const gdb::ref_ptr<T, POLICY>&, const T*)
 inline bool operator!= (const ref_ptr<T, POLICY> &self, const T *other)
..../src/gdb/common/gdb_ref_ptr.h:212:13: note:   template argument deduction/substitution failed:
..../src/gdb/solib-darwin.c:467:19: note:   mismatched types ‘const T*’ and ‘long int’
   if (dyld_bfd != NULL)

That's simply because template type deduction, which happens
before overload resolution, does not consider implicit conversions.
And then there's no overload in the overload set that satisfied
the operation.

Before the gdb_ref_ptr.h patch (this email thread), gdbpy_ref
is not a template, so:

  inline bool operator!= (const gdbpy_ref &self, const PyObject *other);

is left in the overload set, at which point implicit conversions can

I was a bit mystified about why my gdb_unique_ptr shim had == NULL
working without nullptr_t overloads, but I remember now.  It was
because it was using the safe bool idiom to make it work.  I.e.,
adding this to ref_ptr would make operator==/operator!= work without
the nullptr_t overloads too:

  /* "explicit operator bool ()" emulation using the safe bool
     idiom.  */
  typedef void (ref_ptr::*explicit_operator_bool) () const;
  void this_type_does_not_support_comparisons () const {}

  operator explicit_operator_bool () const
    return (m_obj != NULL
           ? &ref_ptr::this_type_does_not_support_comparisons
           : 0);

With this, despite the fact that no operator== candidate template
matches, the compile still manages to call the built-in, non-template:

 bool operator==(member function ptr, long);

> Pedro> Do you have your code in some branch?  It seems none of the
> Pedro> gdbpy_ref stuff is in master yet.
> I pushed it to py-cxx-changes on my github account.

Thanks, that helped.

So the conclusion is that the nullptr_t overloads are necessary because
ref_ptr is now a template.

BTW, notice that both retain_ptr (that proposal I linked to), and unique_ptr
have these same overloads.

Pedro Alves

More information about the Gdb-patches mailing list