This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Smart pointer pretty printers


On 24/02/17 16:08 +0100, Juraj Oršulić wrote:
On Thu, Feb 23, 2017 at 7:05 PM, Jonathan Wakely <jwakely@redhat.com> wrote:
I wasn't entirely convinced it was an improvement, and I think the
patch is significant enough to require a copyright assignment.

Hi Jonathan,

I hope I can convince you that addressing this will remove a major
inconvenience for IDE users. For example, take a look at this page on
the CLion issue tracker, where the issue has been opened in 2015 and
has accumulated 40 votes:
https://youtrack.jetbrains.com/issue/CPP-2496

See https://gcc.gnu.org/ml/libstdc++/2013-04/msg00102.html

At first, I haven't read your message in great detail and assumed that
Michael, in his final message that I have linked, addressed the issues
that you raised (simply because the message came after your message).
Now I see that he didn't. I agree with you, printing a variable
containing a smart shouldn't duplicate information (the pointer
address).

I took a closer look and I think I have come up with a solution.  It
seems that the problem that Tom Tromey has mentioned, that { .... }
replaces the to_string result in case when the printer has children,
is no longer an issue. This means that we can remove the pointer
address from the to_string result, and expose the pointer as a child
like Michael suggested. This ensures that the pointer address is
printed when the pretty printer is recursively invoked on the child.
However, we should (I think?) keep the name of the child synchronized
with how we would access it in regular code, so the member path,
generated by stitching together the printer children names, is valid.
(Introducing a child node named "Managed object" is not valid in this
sense.) Therefore, I propose that we name the child "get()" or
"operator->()".

I have included the patch for the unique pointer printer:

--- libstdcxx/v6/printers.py
+++ libstdcxx/v6/printers.py
@@ -124,11 +124,13 @@ class UniquePointerPrinter:

    def __init__ (self, typename, val):
        self.val = val
+        self.pointer = val['_M_t']['_M_head_impl']
+
+    def children (self):
+        return [('get()', self.pointer)]

    def to_string (self):
-        v = self.val['_M_t']['_M_head_impl']
-        return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),
-                                                       str(v)))
+        return ('std::unique_ptr<%s>' % (str(self.pointer.type.target())))

def get_value_from_list_node(node):
    """Returns the value held in an _List_node<_Val>"""



This is how it looks from the gdb shell, almost like you wanted:

(gdb) print up
$1 = std::unique_ptr<int> = {get() = 0x61bc20}

...and it works from an IDE such as CLion. If you think this is okay,
perhaps this can be expanded to the shared pointer printer, and even
iterator printers, so that the pointed objects can all be explored in
graphical debuggers by expanding the pointers.

This looks promising, thanks. I'll look into making that change, and
something similar to the shared_ptr printer too.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]