В плюсах можно сделать шикарнейший логгер. Во-первых не занимающий
програмной памяти или памяти данных (оперирует адресами текста в
ELF-файле, сам текст в Flash -- отсутствует), во-вторых работающий
быстро, в-третьих умеющий распечатывать enum'ы и другие типы,
в-третьих выдающий компактный бинарный вывод. Который можно имея
ELF файл от этой версии прошивки восстановить в текст. В языке "C"
лучшее что можно сделать -- только первый пункт и последний, причём
последний плохонько.
На первый пункт я давал только что ссылку (http://caxapa.ru/401461). Делается легко.
Если синтаксис и семантика printf'а, то быстро на C не получится. Лучшее что может сделать C -- вызвать функцию с переменным числом аргументов, она может в рантайме, медленно и печально, распарсить строку формата, сериализовать согласно строке аргументы и сериализовать ссылку на строку...
В то же время код на C++ позволяет совершенно фантастическую вещь: строку вида logger("format %d %s %x....", a, b, c) сразу превратить максимально эффективный код, который ничего парсить не будет, а сразу сгенерируются по месту инструкции, ктоорые засунут в нужном формате и нужное место кольцевого буфера и a, и b, и c. В этом мощь C++. Он позволяет генерировать почти что оптимальный машинный код. Компилятор будет генерировать, по заданным правилам, а не ты руками писать.
Третий пункт -- нормально не решается в языке без ООП скорей в языке без Argument Dependent Lookup. Вообще мощь C++ в значительной степени этой "фиче" тоже. Что можно отделить мух от котлет, операции над типами от самих типов. В рамках чистого ООП (как в Delphi, C#) такое невозможно попросту. Это помимо шаблонов и метапрограммирования.
Четвёртый пункт в голом C возможен, но опять же упирается в эффективность кода. Я описывал (и реализовывал) идею сериализации: http://caxapa.ru/976585
На C++ опять же получается по месту генерирать эффективный зависимый от типа выводимых данных код. В голом C так не получится. Т.е. можно всё то же самое написать руками, но это ж чудовищно, писать всё вручную каждый раз, просто написать output(a,b,c,d...) и ожидать эффективного кода -- невозможно.
Про C++:
http://caxapa.ru/907638/ -- о языках программирования и метапрограммировании;
http://caxapa.ru/965849/ -- о многомерности C++ и программировании управлемом типам;
http://caxapa.ru/965825/ -- о преимуществах статического полиморфизма и метапрограммирования;
http://caxapa.ru/965513/ -- о преимуществах C++ по отношению к ошибкам.
http://caxapa.ru/956884/ -- в C++ скрытая сложность вытаскивается наружу, в Python, C# -- прячется, но она везде есть.