bug in libc++

Hi this simple code is causing compilation error.

class Foo
{
public:

Foo(Foo&&) noexcept = default;
Foo& operator=(Foo&&) noexcept = default;

Foo()
{
}

private:

std::vectorstd::string vectorFoo_;
};

see errors here
http://coliru.stacked-crooked.com/a/ab2fb522c4982c72

But if I use libstdc++ it compile fine. So where is the bug libc++ or libstdc++?

Thanks

Even better - your code crashes the ToT clang.

– Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
– Yu Suzuki

Didn’t check your link or try your code, but this might be because std::vector doesn’t have a nothrow move constructor or a nothrow move-assignment operator.

      Steve

Didn’t check your link or try your code, but this might be because std::vector doesn’t have a nothrow move constructor or a nothrow move-assignment operator.

      Steve

I thought that std::vector would have a noexcept move constructor and assignment given that all of it’s member are noexcept in regard of move construction and assignment. Then again, i forgot about the allocator. But that mean that the default allocator is not noexcept when doing a move construction of assignment?

When we do a move construction or assignment of a vector with the default allocator, there shouldn’t be any actual heap allocation going on. no?

Also if it now crash thats is new. I am synched from about 3 days ago and it was compiling with error but not crashing.

Thanks alot!

My initial response was based on the spec - neither vector’s move constructor nor its move-assignment operator are required to be noexcept (true). However, looking at the source for libc++, I see that both of those special member functions have optional noexcept specifications; so when using libc++, at least, it’s possible for std::vector to be nothrow in these cases.

Poking around with your example, I noticed a few interesting things:

  * is_nothrow_move_constructible and is_nothrow_move_assignable both return true for std::basic_string <char>, std::string, and std::vector <std::string>. For that matter, so does std::allocator when templatized on each of those classes. Just to be absolutely certain of this last case, I also checked std::__1::is_nothrow_move_constructible <std::__1::allocator <std::__1::basic_string <char>>> and it’s still true.

  * The compiler complains about your Foo class, essentially claiming that is_nothrow_move_constructible <std::allocator <string>> is false.

So, yeah, a conflict.

A few things to note: std::allocator explicitly defines a copy constructor but no copy-assignment operator. This means that its move constructor and move-assignment operator are implicitly deleted (and that the copy-assignment operator is implicitly defined, though this behavior is deprecated). That means any time you invoke a move special member function, you’re actually getting the copy special member function. In the case of a class like vector, this behavior shouldn’t be a problem for moves since the allocator doesn’t actually get moved/copied - it’s more of a policy class.

All I can figure here is that the noexcept specification is tripping on the allocator type traits because it’s checking them before it has full “visibility” of allocator’s implicit special member functions. I don’t know enough about noexcept to know exactly what’s happening, but my gut feeling, based on explicit testing with is_nothrow_xxx, is that this is a subtle clang bug after all (or possibly an abuse of noexcept specifications by libc++). It would be nice if an actual expert would weigh in, though.

      Steve

I have received (and tested) a patch from Alp Toker for clang which fixes this problem (Manu's original code now compiles w/o errors).
This doesn't seem to have been committed yet.

-- Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
        -- Yu Suzuki