More C++ Idioms/Function Poisoning

Function poisoning
edit

Intent edit

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

Also Known As edit

Motivation edit

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

// header of external library

foo* create_foo();
foo_destroy(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, ...
        foo_destroy(h);
    }
};
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

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

References edit