?

Log in

No account? Create an account

Previous Entry Share Next Entry
Препроцессор C++. Переписать! И дело с концом.
mikelsv
Никогда не знаешь, чем решишь заняться. В это раз это был препроцессор С++.

Собственно проблема: Захотелось написать программу профилирования памяти. Для этого потребовалось перехватить вазовы вот этих чудесных функций: malloc, free, HeapAlloc, HeapFree, LocalAlloc, LocalFree, GlobalAlloc, GlobalFree, VirtualAlloc, VirtualFree, VirtualAllocEx, VirtualFreeEx. И, чтобы не писать кучу кода, было решено написать кучу дефайнов с параметрами функций и использовать их. И вся такая чудесная идея разбилась о суровую действительность компилятора в MSVS. Оказалось, он не умеет разворачивать дефайны. То есть представить строку #define A 1, 2, 3  в #define B(a, b, c) как три параметра, а не один. Ну, не умеет, значит научим. И понеслась.

Сначала я конечно попытался взять свой старый http://mikelsv.livejournal.com/1821.html , но потыкавшись понял, что проще переписать. Ибо технологии ушли далеко и все реализуется намного проще и лучше.

Итого, препроцессор написан, и умеет не только стандартные #команды препроцессора, но и чуть большее расширение. А, самое главное, возможность разворачивать дефайны в параметры.

Для примера:
#define A 1, 2, 3
#define B(a, b, ...) printf(a, __VA_ARGS__ );

Была задача реализовать B("%d %d %d\r\n", 1, 2, 3);  используя параметры из A.  Очквидно, что B("%d %d %d\r\n", A);  сработает совсем не так, так как A будет считаться вторым параметром.
Для решения проблемы был введено обозначение развертки - ::, два двоеточия. Сначала пытался взять всякие #@ или #:, но они плохо вписывались в логику препроцессора. Последний знак вписался более менее хорошо. Хотя, он используется в коде и возможно его стоит сменить.
Так вот, B("%d %d %d\r\n", ::A); говорит препроцессору развернуть A и мы получаем результат аналогичный B("%d %d %d\r\n", 1, 2, 3); Это победа. Я считаю.

Ну и на последок, хочется заметить, что свой препроцессор штука хорошая и раньше импользовались мной для генерации кода и отказа от шаблонов. Теперь же я постепенно все больше использую шаблоны. Имеет смысл задуматься и снова использовать препроцессор для генерации кода. Тем более, что он уже написан и дописать ему новых плагинов пара пустяков. А открывающиеся возможности просто офигенны.