Skip to content

throwing destructors cannot be used with smart pointers #553

@fcelda

Description

@fcelda

Hello.

I hit a problem where FlatArrayMessageReader cannot be used as a C++14 shared pointer. The program fails to compile with capnp 0.6.1 and clang/libcxx 4.0.1 (and 5.0.0). Here is a small reproducer:

#include <memory>
#include <capnp/serialize.h>

int main()
{
	kj::ArrayPtr<capnp::word> array;
	auto reader = std::make_shared<capnp::FlatArrayMessageReader>(array);
	return 0;
}

The compiler doesn't like that the destructor of FlatArrayMessageReader is nothrow(false):

$ clang++ -std=c++14 -Wall -g -O0 -o main main.cpp -lcapnp -lkj
In file included from main.cpp:1:
/usr/local/Cellar/llvm/4.0.1/bin/../include/c++/v1/memory:3813:7: error: exception specification of overriding function is more lax than base version
class __shared_ptr_emplace
      ^
/usr/local/Cellar/llvm/4.0.1/bin/../include/c++/v1/memory:4444:26: note: in instantiation of template class 'std::__1::__shared_ptr_emplace<capnp::FlatArrayMessageReader,
      std::__1::allocator<capnp::FlatArrayMessageReader> >' requested here
    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
                         ^
/usr/local/Cellar/llvm/4.0.1/bin/../include/c++/v1/memory:4810:29: note: in instantiation of function template specialization
      'std::__1::shared_ptr<capnp::FlatArrayMessageReader>::make_shared<kj::ArrayPtr<capnp::word> &>' requested here
    return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
                            ^
main.cpp:7:21: note: in instantiation of function template specialization 'std::__1::make_shared<capnp::FlatArrayMessageReader, kj::ArrayPtr<capnp::word> &>' requested here
        auto reader = std::make_shared<capnp::FlatArrayMessageReader>(array);
                           ^
/usr/local/Cellar/llvm/4.0.1/bin/../include/c++/v1/memory:3739:13: note: overridden virtual function is here
    virtual ~__shared_weak_count();
            ^
1 error generated.

Is wonder why is the destructor noexcept(false). I found some comments in commit af6bb03 but I don't fully understand the reasons. I have never encountered a case where throwing in destructor would be wise especially because catching these exceptions is confusing.

Do the reasons for throwing in capnp's destructors still prevail?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions