Why do C++ libraries and frameworks never use smart pointers?

laurent picture laurent · Apr 26, 2012 · Viewed 26.1k times · Source

I read in a few articles that raw pointers should almost never be used. Instead they should always be wrapped inside smart pointers, whether it's scoped or shared pointers.

However, I noticed that frameworks like Qt, wxWidgets and libraries like Boost never return nor expect smart pointers, as if they were not using them at all. Instead, they return or expect raw pointers. Is there any reason for that? Should I stay away from smart pointers when I write a public API, and why?

Just wondering why smart pointers are recommended when many major projects seem to avoid them.

Answer

Jon Purdy picture Jon Purdy · Apr 27, 2012

Apart from the fact that many libraries were written before the advent of standard smart pointers, the biggest reason is probably the lack of a standard C++ Application Binary Interface (ABI).

If you’re writing a header-only library, you can pass around smart pointers and standard containers to your heart’s content. Their source is available to your library at compile time, so you rely on the stability of their interfaces alone, not of their implementations.

But because of the lack of standard ABI, you generally cannot pass these objects safely across module boundaries. A GCC shared_ptr is probably different from an MSVC shared_ptr, which too can differ from an Intel shared_ptr. Even with the same compiler, these classes are not guaranteed to be binary compatible between versions.

The bottom line is that if you want to distribute a prebuilt version of your library, you need a standard ABI on which to rely. C doesn’t have one, but compiler vendors are very good about interoperability between C libraries for a given platform—there are de facto standards.

The situation is not as good for C++. Individual compilers can handle interoperation between their own binaries, so you have the option of distributing a version for every supported compiler, often GCC and MSVC. But in light of this, most libraries just export a C interface—and that means raw pointers.

Non-library code should, however, generally prefer smart pointers over raw.