Russian Qt Forum

Qt => Общие вопросы => Тема начата: Akon от Май 12, 2012, 09:52



Название: Q_VERIFY
Отправлено: Akon от Май 12, 2012, 09:52
Вот в N-й раз плююсь, что нет Q_VERIFY - это расхожий макрос, который в дебаге работатет как assert, а в релизе просто вычисляет выражение - свой аргумент. Т.е.
Код:
QList<Foo> foos;

// Необходимо удалить объект, который должен быть в контейнере

// хорошо бы так:
Q_VERIFY(foos.removeOne(foo));

// а приходится так:
{
    bool ok = foos.removeOne(foo);
    Q_ASSERT(ok && "foos.removeOne(foo)");
    Q_UNUSED(ok);
}

Понятно, что написать такой макрос - дело трех секунд, но почему в Qt его нет? Или я чего не вижу?


Название: Re: Q_VERIFY
Отправлено: andrew.k от Май 12, 2012, 19:03
Вот в N-й раз плююсь, что нет Q_VERIFY - это расхожий макрос, который в дебаге работатет как assert, а в релизе просто вычисляет выражение - свой аргумент. Т.е.
Код:
QList<Foo> foos;

// Необходимо удалить объект, который должен быть в контейнере

// хорошо бы так:
Q_VERIFY(foos.removeOne(foo));

// а приходится так:
{
    bool ok = foos.removeOne(foo);
    Q_ASSERT(ok && "foos.removeOne(foo)");
    Q_UNUSED(ok);
}

Понятно, что написать такой макрос - дело трех секунд, но почему в Qt его нет? Или я чего не вижу?
Интересно, какой ответ ты ожидаешь тут получить на такой вопрос? ;D


Название: Re: Q_VERIFY
Отправлено: Igors от Май 12, 2012, 19:42
Чтобы не вякало unused можно так
Код
C++ (Qt)
bool ok;
ok = foos.removeOne(foo);
 
Из той же оперы но, на мой взгляд, более интересно/актуально - а как с макро для отладочных печатей?


Название: Re: Q_VERIFY
Отправлено: Akon от Май 14, 2012, 11:34
Цитировать
Интересно, какой ответ ты ожидаешь тут получить на такой вопрос?
Ну, возможно, в Qt есть что-то такое, и я просто об этом не знаю: мне укажут. Или выразят солидарность, соответственно, я укреплюсь во мнении, что я не свелосипедил.

Код:
bool ok;
ok = foos.removeOne(foo);
Будет вякать, "ok" же не используется.

Цитировать
Из той же оперы но, на мой взгляд, более интересно/актуально - а как с макро для отладочных печатей?
Поясните.


Название: Re: Q_VERIFY
Отправлено: DmitryM от Май 14, 2012, 12:35
QVERIFY и QVERIFY2 не подходят?


Название: Re: Q_VERIFY
Отправлено: Akon от Май 14, 2012, 13:21
Нет, это для тестов.


Название: Re: Q_VERIFY
Отправлено: Igors от Май 14, 2012, 14:25
Будет вякать, "ok" же не используется.
На Вындоуз не помню, но gcc/icc - точно нет

По поводу отладочных печатей. Пример
Код
C++ (Qt)
#if DEBUG_PRINT
printf("[%d] = %f\n", i, val[i]);
..
#endif
 
Однако число таких DEBUG_PRINT неуклонно увеличивается для разных cpp. Иногда проще снести и, да, потом возможно написать снова


Название: Re: Q_VERIFY
Отправлено: Akon от Май 14, 2012, 15:19
Да будет, переменная ж реально не используется! Вот у меня под рукой MinGW (GCC-TDM 4.6.2) - вякнул.

Цитировать
#if DEBUG_PRINT
 printf("[%d] = %f\n", i, val);
 ..
#endif

Каждый раз писать #if DEBUG_PRINT/#endif не по уму. По уму:
Код:
DEBUG_PRINT("[%d] = %f\n", i, val[i]);
где DEBUG_PRINT имеет переменное число аргументов (как printf) и дает нулевой оверхэд в релизе. Делается это через вспомогательный функтор, с членом
void __cdecl operator()(const char* format, ...)
Соответственно, DEBUG_PRINT в дебаге раскрывается в локальный функтор, в релизе - в пустышку.

Еще замечу, что Qt-овские функции
void qDebug ( const char * msg, ... ), qWarning() и т.п. дают ненулевой релизный оверхэд.


Название: Re: Q_VERIFY
Отправлено: Igors от Май 14, 2012, 15:54
Еще замечу, что Qt-овские функции
void qDebug ( const char * msg, ... ), qWarning() и т.п. дают ненулевой релизный оверхэд.
Совсем ненулевой, да и на Qt свет клином не сошелся

Каждый раз писать #if DEBUG_PRINT/#endif не по уму. По уму:
Код:
DEBUG_PRINT("[%d] = %f\n", i, val[i]);
где DEBUG_PRINT имеет переменное число аргументов (как printf) и дает нулевой оверхэд в релизе. Делается это через вспомогательный функтор, с членом
void __cdecl operator()(const char* format, ...)
Соответственно, DEBUG_PRINT в дебаге раскрывается в локальный функтор, в релизе - в пустышку.
Неясно зачем оператор () если можно просто ф-цию напр PrintDebug, а передавать va_list все равно придется

Но далеко не всегда печать ложится в 1 строку, напр
Код
C++ (Qt)
#if DEBUG_PRINT
printf("[%d] = ", i);
for (int j = 0;ji < 8; ++j) {
 printf("%f, ", i, val[i].mRadius[j]);
 maxRad = MAX(maxRad, val[i].mRadius[j]))
}
printf(", max = %f\n", maxRad);
#endif
 


Название: Re: Q_VERIFY
Отправлено: Akon от Май 14, 2012, 16:40
Цитировать
Неясно зачем оператор () если можно просто ф-цию напр PrintDebug, а передавать va_list все равно придется
ИМХО, очень желательно, чтобы DEBUG_PRINT выводил контекст (__FILE__, __FUNCTION__ и т.п.). Т.е. в ваш PrintDebug будет передаваться дополнительная информация. Если не сложно, покажите как это сделать, чтобы использование осталось таким же лаконичным: DEBUG_PRINT("[%d] = %f\n", i, val); (у меня получались двойные скобки, дополнительные запятые, может чего-то там еще - не помню, вообщем на каждый вызов приходилось писать несколько лишних символов). Функтор позволяет в точке вызова иметь контекст (__FILE__, __FUNCTION__ и т.п.), переданный посредством конструктора.

Цитировать
Но далеко не всегда печать ложится в 1 строку, напр
Полностью согласен.


Название: Re: Q_VERIFY
Отправлено: Igors от Май 14, 2012, 18:22
С отловом фатальных ошибок все довольно неплохо - макрос разворачивается в assert, и все дела. Однако гораздо чаще надо печатать (многочисленные) данные на этапе выполнения чтобы осознать а что же происходит и почему результат не соответствует ожидаемому (хотя ничто не вылетает). Пользуюсь примитивным #if, здесь мне добавить нечего. Самому хотелось бы узнать о более тонких методах/подходах