Manual resource management in low level C-style C++ code might be annoying. It's not practical to create good enough RAII wrappers for every single C API you use, but approaches with goto cleanup or loads of nested if (success) hurt readability.
A Go-inspired defer macro to the rescue! The usage is as simple as that:
void* p = malloc(0x1000); defer [&] { free(p); };
The deferred lambda will be executed on scope exit, no matter how it happens: you can return from any point, throw an exception (if allowed), or even use a goto to an outer scope.
Macro implementation is concise and relies on basic features of C++17 (Clang 5+, GCC 7+, MSVC 2017+):
#ifndef defer template <typename T> struct Deferrer { T f; Deferrer(T f) : f(f) { }; Deferrer(const Deferrer&) = delete; ~Deferrer() { f(); } }; #define TOKEN_CONCAT_NX(a, b) a ## b #define TOKEN_CONCAT(a, b) TOKEN_CONCAT_NX(a, b) #define defer Deferrer TOKEN_CONCAT(__deferred, __COUNTER__) = #endif
It is truly zero-cost and doesn't rely on C runtime or standard library, so it can be used even in kernel development.