fk0, легенда (13.11.2019 08:58 - 09:09, просмотров: 691) ответил =AlexD= на Не знаю на сколько оправданы твои труды, потому как GCC умеет сам проверять аргументы printf на соответствие шаблону целой кучей опций семейства -Wformat
Так рассуждать, труды автора fmtlib тоже не оправданы. Мол есть printf, он всё делает. Но это не так, очень даже оправданы. Там много ньюансов. Основной -- вынос парсинга строки формата в compile time, потому, что printf работает не быстро. По http://user-images.githubusercontent.com/576385/54883977-9fe8c000-4e28-11e9-8bde-272d122e7c52.jpg
https://github.com/fmtlib/fmt#benchmarks
ссылке бенчмарки, и на картинке тоже. Можно уже сделать выводы. Потом есть такой важный ньюанс, что variadic argument functions, унаследованные от C, то ещё дерьмище: они вообще не инлайнятся и успешно стирают информацию о типах в итоге дальнейшая генерация сколько-нибудь эффективного кода -- считай невозможна. Когда оно заменяется на variadic template становится сильно лучше. В compile time оказывается не только парсинг строки формата, но и фактически само преобразование типа в строку или что-то ещё, если значение является константой. Более того, код становится линейным, там нет условий, переходов, там просто заведомо наперёд известная последовательность операций по записи значения в поток
Потом же printf-подобный интерфейс функции, это лишь интерфейс, не значит, что она функционал имеет ровно такой же. У меня это сериализатор в бинарный формат вообще. Т.е. общий-то здесь только фронтенд, а бэкенд может быть совершенно другой. Вообще это подход к теме бинарного логгера с другой стороны. На сахаре я как-то описывал ещё C-only реализацию. Идея в том, что выводимые строки можно хранить в сегменте памяти фактически не линкуемом в реальный бинарник. И вместо самих строк распечатывать их адреса. Это экономит программную память. Идею можно усовершенствовать, если передавать не адреса, а индекс (порядковый номер) строки (в отсутствующей секции), на индекс нужно меньше бит для кодирования. Разумеется, тот кто декодирует бинарный лог должен иметь ELF-файл с не сострипанными секциями, в которых есть реальные сообщения.
Кроме того, отдельной интересной темой является распечатка типов не предусмотренных в printf, хотя бы в строковом виде. В основном, конечно, это нужно для логгеров, и в основном это enum'ы. Потому, что когда логгер реально большого проекта их начинает выводить, то воспринимать их в числовом виде невозможно: нужно за каждой циферкой лезть в исходники, и смотреть соответствие. А в разных версиях ещё они добавляются, меняются -- сделать скрипт, чтоб автоматически текст уже конвертировал, тоже не просто. И здесь такая получается тема, что для соответствия формата пишется "%d", а на деле оказывается "%s". И нужно во-первых понимать какой тип имеет конкретный аргумент, что это такой тип, который имеет функцию конверсии в строку, поменять "%d" на "%s", поменять сам аргумент с некого условного enumValue на вызов stringify(enumValue), и только потом вызвать printf. Удивительное дело, но оказывается это можно накрутить макросами поверх обычной vararg функции, только выглядит атас как жутко и опять же решение а-ля fmtlib просто концептуально чище.
Идея конечно в сохранении "фронтенда", как интерфейса функции printf. Удобного для использования, всем привычного, проверенного практикой и временем. Альтернативы, вроде iostreams, успели показать свою несостоятельность. Громоздко, непонятно, неудобно, легче наделать ошибок. нужен не оператор вывода, а шаблон (текста), в который можно подставить данные аргументы.
[ZX]