More C++ Idioms/Function Poisoning

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Function poisoning
[edit | edit source]

Intent[edit | edit source]

Hide or prohibit the usage of certain functions, favoring better alternatives.

Also Known As[edit | edit source]

Motivation[edit | edit source]

Often, when interacting with libraries that have a C or pre-c++11 interface, since modern C++ is more expressive, it would be very convenient to hide (from myself and other people that are working on the same project), all (or just many) functions that allocate memory and return a raw pointer, and replace them with something more RAII-friendly.

Solution and Sample Code[edit | edit source]

// header of external library

foo* create_foo();

// our header, with our enhanced version

struct foo_deleter {
    void operator()(foo* h) {
        // foo_destroy provided by the 3rd party library as function, macro, ...
using unique_foo = std::unique_ptr<foo, foo_deleter>;

inline unique_foo create_unique_foo() {
    // we do not have poisoned create_foo yet!
    return unique_foo{create_foo()};
#pragma GCC poison create_foo
// from now on, no-one can use create_foo again!
// at least with GCC and clang

Guideline for banning a function:

A function g is a strict replacement of a function f of a library l if

   g provides clear benefits over f.
   g can act as a drop-in replacement for f, which means
       it can interact with the library l without writing more than one line of glue code that has no particular drawbacks.
       updating f to g in the working codebase is a trivial operation.
       the cost of removing f is not too high.
   g does not have any drawback compared to f, in particular
       it does not add any measurable runtime overhead compared to f.
       it does not add any new dependency
       it cannot be less type-safe, exception-safe or thread-safe
       it cannot introduce new kinds of programming errors
   g does not reduce readability or hides intent compared to f
       there is no need to document what g does since it should do the same of f, only the benefits if those are not clear to everyone

And therefore, if g is a strict replacement of f, we can apply the banning policy on f in our codebase.

Known Uses[edit | edit source]

Replace a function which cannot be removed (for example if it is part of an external library) with a function with improved functionality.

Related Idioms[edit | edit source]

References[edit | edit source]