Архив рубрики: C++

Лаконичный макрос defer для C++

Ручное управление ресурсами в низкоуровневом си-подобном коде на C++ — довольно хлопотное дельце. Создание достойных RAII-врапперов для каждого используемого сишного API не всегда практично, а использование подходов с goto cleanup или множеством вложенных if (success) вредит читаемости кода.

Макрос defer, вдохновленный Go, как никогда кстати! Использовать его просто:

void* p = malloc(0x1000);
defer [&] { free(p); };

Отложенная лямбда будет выполнена при выходе из области видимости, независимо от того, будет ли выполнен return, брошено исключение (если разрешено), или даже выполнен goto наружу.

Реализация макроса лаконична и полагается на базовые возможности 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

Данный макрос по-настоящему zero-cost и не зависит от рантайма C или стандартной библиотеки, поэтому его можно использовать даже в разработке под ядро ОС.

Читать далее

VS2005 Win32 Wizard MOD v1.0b [19.03.2008]

Мне всегда не нравились параметры по умолчанию, которые устанавливала Visual Studio 2005 при создании приложений для Win32. Каждый раз при создании нового проекта (даже самого мизерного) приходилось каждый раз отключать Unicode, Precompiled Headers (в небольших программах это ни к чему), включать статическую линковку всех необходимых библиотек для Release версии. Хотелось лишить себя этих хлопот.

Первые же исследования показали, что для всех мастеров создания проектов в VS2005 используется HTML и специальный JScript. Немного разобравшись в нем, я сделал множество удобных изменений. Возможно, кому-нибудь тоже пригодится.

Читать далее