This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFA 3/3] Remove cleanups from break-catch-syscall.c
- From: Pedro Alves <palves at redhat dot com>
- To: Tom Tromey <tom at tromey dot com>, Simon Marchi <simon dot marchi at ericsson dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Wed, 25 Oct 2017 11:38:30 +0100
- Subject: Re: [RFA 3/3] Remove cleanups from break-catch-syscall.c
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=palves at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 82A214E33A
- References: <20171018040645.7212-1-tom@tromey.com> <20171018040645.7212-3-tom@tromey.com> <280a7994-38a6-2138-b199-8902ee2651b0@ericsson.com> <87tvynrg8h.fsf@tromey.com>
On 10/25/2017 05:41 AM, Tom Tromey wrote:
> Simon> It is not enough to assign holders.back ().c_str () (after having pushed the string in
> Simon> the vector), because when the vector gets reallocated it can now point to stale memory.
> Simon> I think we have to do it in two pass, prepare the vector of std::string, and then get
> Simon> pointers to the strings.
>
> Sorry about that. I think I considered this after the earlier review
> and believed that the resizing wouldn't affect the locations; my
> thinking being that growing the vector must surely use the move
> constructor to move the strings into place -- since isn't this pretty
> much the whole reason rvalues even exist? But perhaps this doesn't
> happen sometimes for some reason.
std::vector will copy instead of move on resize if:
- the element type is copyable and,
- the move ctor is not marked noexcept.
This has to do with strong/basic exception guarantees.
But in this case the element type is a std::string, and
std::string can (and most implementations do) make use of
the SSO (small string optimization). I.e., very simplified,
something like:
string
{
struct free_store_data
{
char *ptr;
size_t capacity;
};
union
{
char internal_buf[sizeof (free_store_data)];
free_store_data free_store_buf;
} m_data;
size_t m_size;
};
When the string data fits in the internal buffer, moving the
object must mean copying the internal buffer
and in that case "moved_from.c_str()" will still be left
pointing to the internal buffer of the moved-from
std::string.
Thanks,
Pedro Alves