[libcxx-dev] std::vector using copy constructor on existing elements during reserve()

Eric Fiselier via libcxx-dev libcxx-dev at lists.llvm.org
Wed Apr 17 10:37:41 PDT 2019


The only reason we call the copy constructor is to provide the strong
exception safety guarantee (which arguably may have been a mistake).
Without exceptions the guarantee is satisfied trivially.

I think we should move the objects. Doing the more efficient thing provides
value to the user.

Google compiles a ton of code without exceptions. I will experiment with
making `move_if_noexcept` always move and report back.

/Eric




On Wed., Apr. 17, 2019, 1:12 p.m. Louis Dionne, <ldionne at apple.com> wrote:

>
>
> On Apr 17, 2019, at 12:39, Duncan P. N. Exon Smith <dexonsmith at apple.com>
> wrote:
>
> I'm curious about how people feel this should/could behave with
> -fno-exceptions.  IIRC, Libc++ calls the copy constructor (following the
> standard), but -fno-exceptions isn't really standard, and from a user
> perspective that doesn't make sense.  `noexcept` is essentially meaningless
> with -fno-exceptions.
>
>
> I personally feel like it would be surprising if -fno-exceptions caused
> the move constructor to be called instead of the copy constructor. My
> mental model is that -fno-exceptions only disables exceptions as a language
> feature, but doesn't really instruct libraries to provide a different API
> (even though the difference in this case is very small). Instead, I feel
> like it would make more sense if "everything" was implicitly marked
> noexcept when -fno-exceptions is used (because that's really the case). The
> library would behave optimally with -fno-exceptions without having to do
> anything special.
>
> Louis
>
>
> Thoughts?
>
> On Apr 16, 2019, at 23:19, Eric Fiselier via libcxx-dev <
> libcxx-dev at lists.llvm.org> wrote:
>
>
>
> On Tue, Apr 16, 2019 at 2:25 PM Michael Narigon via libcxx-dev <
> libcxx-dev at lists.llvm.org> wrote:
>
>> std:vector is using the element copy constructor on existing elements
>> during its resizing operation in reserve(). I would expect it to use the
>> move constructor for efficiency. Is this intended behavior?
>>
>
> Yes, this behavior is mandated by the standard. The copy constructor is
> used when the move constructor is not noexcept. From cppreference's
> `std::move_if_noexcept` documentation:
>
> std::vector::resize
>> <https://en.cppreference.com/w/cpp/container/vector/resize>, which may
>> have to allocate new storage and then move or copy elements from old
>> storage to new storage.
>> If an exception occurs during this operation, std::vector::resize
>> <https://en.cppreference.com/w/cpp/container/vector/resize> undoes
>> everything it did to this point, which is only possible if
>> std::move_if_noexcept was used to decide whether to use move
>> construction or copy construction. (unless copy constructor is
>
> not available, in which case move constructor is used either way and the
>> strong exception guarantee may be waived)
>
>  https://en.cppreference.com/w/cpp/utility/move_if_noexcept
>
> If you add `noexcept` to your move constructor, vector should call the
> move constructor.
>
>
>
>
>>
>> This is with the libc++ delivered with Xcode 10.1.
>>
>> Attached is a sample program displaying the behavior.
>> _______________________________________________
>> libcxx-dev mailing list
>> libcxx-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev
>>
> _______________________________________________
> libcxx-dev mailing list
> libcxx-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/libcxx-dev/attachments/20190417/e08fd471/attachment.html>


More information about the libcxx-dev mailing list