[llvm-dev] RFC: [SmallVector] Adding SVec<T> and Vec<T> convenience wrappers.

James Y Knight via llvm-dev llvm-dev at lists.llvm.org
Wed Dec 2 09:51:51 PST 2020


On Wed, Dec 2, 2020 at 12:05 AM Chris Lattner <clattner at nondot.org> wrote:

> On Dec 1, 2020, at 4:07 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com>
> wrote:
>
>
> Can you spell this out for me?  Why do we need noexcept if we’re building
> with -fno-exceptions?  What is going on here?
>
>
> Sure. It's a bit convoluted. Here's my understanding:
>
> First, here's why std::vector has this behaviour:
> - std::vector grow operations need to transfer their existing elements
> over to the new storage.
> - The grow operations are usually required to meet the "strong exception
> guarantee": if something throws, this function has no effect.
> - If move operations throw, you can't provide this guarantee unless you
> copy (you can't move back the elements that have been half-moved over, in
> case another exception is thrown; but if it was just a copy, the original
> storage still has the elements safely unmodified).
> - There's a caveat / carve out, that if T cannot be copy-constructed AND
> T's move constructor is not noexcept, then the guarantee is waived (since
> there's no way to implement it).
> - Implementation is to call std::move_if_noexcept (
> https://en.cppreference.com/w/cpp/utility/move_if_noexcept), which moves
> if it's a noexcept operation, or if T is not copy-constructible.
>
> Second, here's why the behaviour doesn't change when -fno-exceptions:
> - -fno-exceptions does NOT imply `noexcept` (maybe it should?, but it
> doesn't).
> - This is implemented by detecting via SFINAE whether something is
> `noexcept` (maybe std::vector::resize/push_back/etc should have a special
> case? but that's controversial).
>
> IMO, until all the C++ standard libraries and host compilers that we
> support being built with will consistently use std::move on grow operations
> in std::vector in -fno-exceptions mode, we should only use std::vector when
> we absolutely have to. It's not designed for -fno-exceptions codebases
>
>
> Wow, thank you for the great explanation.  I agree with you that this
> seems like a pretty credible reason why we can’t depend on every host
> std::vector to do what we need, so we should use something like an
> llvm::Vector.
>

I strongly disagree here. Not wanting to bother to add 'noexcept' to
user-defined move-constructors is a poor justification for switching to a
different vector type. Perhaps there are *other* reasons which might
justify avoiding std::vector, but not that...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201202/a3d519e3/attachment.html>


More information about the llvm-dev mailing list