Artificial truth

archives | latest | homepage | atom/rss/twitter

The more you see, the less you believe.

My favourite C++ footgun
Sun 13 June 2021 — download

I'm currently learning C++ to be able to do meaningful contributions to OpenMW, so I've been reading a lot of code, and a couple of books on the topic.

But it's in Effective C++, by Scott Meyers, Item 17, that I found the most amazing trigger-happy footgun example:

processWidget(std::shared_ptr<Widget>(new Widget), priority());

std::shared_ptr is a reference counting implementation: it will automatically destroy the object it owns when there is no more std::shared_ptr owning it.

Yet this code can result in a memory leak.

At first, I thought about a weird interaction between std::shared_ptr and new, when the constructor of Widget fails, but this case is handled by the C++ runtime.

The first trick here is that function parameters evaluation order is unspecified, meaning that new Widget might be called, then priority(), then the value returned by new Widget is passed to std::shared_ptr<Widget>(…). The second one is there since this is C++, priority() might raise an exception, meaning that new Widget will be called, but never passed to std::shared_ptr, and thus never deleted!

As AnyOldName3 added after reading this blogpost, this might be why there is std::make_shared, with std::make_shared<Widget>() being kinda equivalent to std::shared_ptr<Widget>(new Widget).

edit: Made it to hackernews' frontpage, with a web server running on 64MiB of ram and a single core.