Russian Qt Forum

Программирование => С/C++ => Тема начата: lesav от Октябрь 17, 2012, 11:03



Название: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 11:03
Уверен, что кому нибудь пригодится.

Макрос форматированного вывода в терминальное окно
Код
C++ (Qt)
#include <QRegExp>
 
#define stringify(v1) #v1
#define quote(v1)  stringify(v1)
 
#define STIP_FUNC \
   QString::fromAscii(Q_FUNC_INFO).replace( \
       QRegExp("^.+\\s((?:[\\w\\d]+::)+)?([\\w\\d\\<\\>~]+)(?:\\(.*\\)).*$"), \
       QString(QLatin1String("<\\1\\2()>"))).toAscii().data()
 
#define DEBUG(...)     qDebug()   << __FILE__  ":"  quote(__LINE__) << STIP_FUNC << "\t" ##__VA_ARGS__
#define WARNING(...)   qWarning() << __FILE__  ":"  quote(__LINE__) << STIP_FUNC << "\t" ##__VA_ARGS__

Использование:
Код
C++ (Qt)
DEBUG()   << m_listLastMsg.size() << QString("TEST_1");
WARNING() << m_listLastMsg.size() << QString("TEST_2");
Выведет в терминал что то подобное
Код
C++ (Qt)
..\..\Prog\src\glob_logger.cpp:205 <G_Logger::showMsg()> 30  "TEST_1"
..\..\Prog\src\glob_logger.cpp:206 <G_Logger::showMsg()> 30  "TEST_2"


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: Bepec от Октябрь 17, 2012, 12:09
Я думаю у каждого первого, второго и третьего программиста уже были такие макросы. (Были, ибо макросы - это плохо по мнению большинства).

а STIP_FUNC зачем?


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: kambala от Октябрь 17, 2012, 13:19
не совсем понятно зачем нужны __VA_ARGS__ при таком использовании


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 13:49
а STIP_FUNC зачем?

STIP_FUNC это STRIP_FUNC (Клавиатура не хочет иногда печатать r)
Название говорит само за себя. 
Q_FUNC_INFO генерит слишком длинный вывод, QRegExp вынимает из него наименование класса и его функцию.

Были, ибо макросы - это плохо по мнению большинства
Ну тогда давайте все вместе отажемся еще и от шаблонов.  ))))


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: Bepec от Октябрь 17, 2012, 13:51
Не путать шаблоны и макросы, горячее и холодное, петухов и буржуев.

Макрос ваш в коде будет понятен только вам. И только после нахождения его объявления и пары минут втупки возможно познать его сакральный смысл.

PS REGEXP на каждый вывод не ахрененно ли тормозит программу? Ради праздного интереса спрашиваю.


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 13:54
... зачем нужны __VA_ARGS__ при таком использовании
Это неизвестные аргументы(и их количество) которые вы подсовываете макросу.

Можно ведь использовать и так
Код
C++ (Qt)
WARNING()<< m_listLastMsg.size()
        << QString("TEST_2")
        << "my const char string"
        << 134
        << (QStringList()<< "dssds" << "sdsd" )
        << 152.25F;


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 14:06
PS REGEXP на каждый вывод не ахрененно ли тормозит программу? Ради праздного интереса спрашиваю.

Я не призывал его использовать везде. А вот при отладке программы он оказывается очень полезным.

Его можно окружить классом который будет вести логирование в Вашем ПО. И при включении логирования с уровнем "debug" REGEXP будет "на каждый вывод ахрененно тормозить программу" и записывать лог с избыточной информацией для более детального анализа что происходит в Вашем ПО.

Извиняюсь, если мой пост нарушил ваше душевное равновесие.


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 14:08
Не путать шаблоны и макросы, горячее и холодное, петухов и буржуев.
Извиняюсь, тут я конечно погорячился! ))))


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: mutineer от Октябрь 17, 2012, 14:11
... зачем нужны __VA_ARGS__ при таком использовании
Это неизвестные аргументы(и их количество) которые вы подсовываете макросу.

Можно ведь использовать и так
Код
C++ (Qt)
WARNING()<< m_listLastMsg.size()
        << QString("TEST_2")
        << "my const char string"
        << 134
        << (QStringList()<< "dssds" << "sdsd" )
        << 152.25F;

А как в приведенном примере поможет __VA_ARGS__ ?


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 14:26
Поможет, попробуйте мой пример, он работает в mingw/msvc


Название: Re: Макрос для лаконичного отображения отла&#
Отправлено: mutineer от Октябрь 17, 2012, 14:28
Поможет, попробуйте мой пример, он работает в mingw/msvc

Почему-то мне всегда казалось что __VA_ARGS__ содержит неименованые аргументы, переданные макросу в скобках (причем вместе с запятыми между ними). В данном примере __VA_ARGS__ не нужен, как и ## перед ним (зачем оно тут, кстати?)


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: Bepec от Октябрь 17, 2012, 14:42
Моё душевное равновесие спокойно и незыблемо - груз погибших пирожков служит ему якорем.

А вопрос быстродействия меня действительно интересует - я занимаюсь ПО для общения с устройствами по RS-485. Задержка в 5-10 мс порушит нахфиг всё общение с устройствами :)

Проверьте скорость выполнения даже простейшим elapsed, если можете :)


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 14:51
Моё душевное равновесие спокойно и незыблемо - груз погибших пирожков служит ему якорем.
)))))  А у меня чтото болтанка с утра, пойду сейчас тож перекушу.

А вопрос быстродействия меня действительно интересует - я занимаюсь ПО для общения с устройствами по RS-485. Задержка в 5-10 мс порушит нахфиг всё общение с устройствами :)
Не поверите, но с такими девайсам я тоже работал, и стопудово обмен рухнет если информацию по каждому байту отправлять в терминал.
А вот если в паузах между отсылкой и приемом то запросто все работать будет.


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: Bepec от Октябрь 17, 2012, 14:53
К сожалению в системе сбора данных не бывает перерывов :) Имеется только спад активности. И даже в эти моменты 7 мс - слииииишком много :)

PS а сколько сил вложено, чтобы отправка/посылка занимали по минимуму, это не описать :D


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: lesav от Октябрь 17, 2012, 15:02
от RegExp можно отказаться только в msvc, т.к. __FUNCTION__ в нем возвращает класс::функ
А вот в mingw облом, приходиться вытаскивать эти значения из Q_FUNC_INFO


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: Bepec от Октябрь 17, 2012, 15:13
Простейший цикл от 1 до 10000. Измеряется elapsed(QTime).

Ваш вариант        1215-1374    мс. (рандомно)
Просто qDebug()    800-1100     мс.
Без вывода            0                мс :D

Единичный вызов занимает на 1-3 мс больше, чем qDebug(). Видимо RegExp подтормаживает.

Вывод: Можно использовать там, где нет особых требований. Да и подходит оно больше для критических :)


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: kambala от Октябрь 17, 2012, 15:14
Поможет, попробуйте мой пример, он работает в mingw/msvc

Почему-то мне всегда казалось что __VA_ARGS__ содержит неименованые аргументы, переданные макросу в скобках (причем вместе с запятыми между ними). В данном примере __VA_ARGS__ не нужен, как и ## перед ним (зачем оно тут, кстати?)
вот именно поэтому я и задал свой вопрос. чтобы __VA_ARGS__ использовались, использование макроса должно быть таким: DEBUG("hello") (в текущей реализации ничего кроме строки не сработает). ## конкатенирует параметры с макросом, нужно для строк.


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: mutineer от Октябрь 17, 2012, 15:16
Поможет, попробуйте мой пример, он работает в mingw/msvc

Почему-то мне всегда казалось что __VA_ARGS__ содержит неименованые аргументы, переданные макросу в скобках (причем вместе с запятыми между ними). В данном примере __VA_ARGS__ не нужен, как и ## перед ним (зачем оно тут, кстати?)
вот именно поэтому я и задал свой вопрос. чтобы __VA_ARGS__ использовались, использование макроса должно быть таким: DEBUG("hello") (в текущей реализации ничего кроме строки не сработает). ## конкатенирует параметры с макросом, нужно для строк.

разве ## конкатенируют не левую и правую часть?


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: Igors от Октябрь 17, 2012, 15:39
Я тоже заинтересовался, глянул гуглу
http://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick (http://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick)


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: kambala от Октябрь 17, 2012, 16:01
действительно, немного перепутал.

но суть в том, что ТС непонятно зачем приплёл эти __VA_ARGS__ в свой макрос


Название: Re: Макрос для лаконичного отображения отладочного вывода
Отправлено: gogi от Октябрь 18, 2012, 10:23
Я думаю у каждого первого, второго и третьего программиста уже были такие макросы. (Были, ибо макросы - это плохо по мнению большинства).

Не были, а есть. Потому что имя функции и место в коде можно узнать только от препроцессора.