Russian Qt Forum
Ноябрь 26, 2024, 00:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Q_VERIFY  (Прочитано 5572 раз)
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 его нет? Или я чего не вижу?
Записан
andrew.k
Гость
« Ответ #1 : Май 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 его нет? Или я чего не вижу?
Интересно, какой ответ ты ожидаешь тут получить на такой вопрос? Смеющийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Май 12, 2012, 19:42 »

Чтобы не вякало unused можно так
Код
C++ (Qt)
bool ok;
ok = foos.removeOne(foo);
 
Из той же оперы но, на мой взгляд, более интересно/актуально - а как с макро для отладочных печатей?
Записан
Akon
Гость
« Ответ #3 : Май 14, 2012, 11:34 »

Цитировать
Интересно, какой ответ ты ожидаешь тут получить на такой вопрос?
Ну, возможно, в Qt есть что-то такое, и я просто об этом не знаю: мне укажут. Или выразят солидарность, соответственно, я укреплюсь во мнении, что я не свелосипедил.

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

Цитировать
Из той же оперы но, на мой взгляд, более интересно/актуально - а как с макро для отладочных печатей?
Поясните.
« Последнее редактирование: Май 14, 2012, 11:38 от Akon » Записан
DmitryM
Гость
« Ответ #4 : Май 14, 2012, 12:35 »

QVERIFY и QVERIFY2 не подходят?
Записан
Akon
Гость
« Ответ #5 : Май 14, 2012, 13:21 »

Нет, это для тестов.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 14, 2012, 14:25 »

Будет вякать, "ok" же не используется.
На Вындоуз не помню, но gcc/icc - точно нет

По поводу отладочных печатей. Пример
Код
C++ (Qt)
#if DEBUG_PRINT
printf("[%d] = %f\n", i, val[i]);
..
#endif
 
Однако число таких DEBUG_PRINT неуклонно увеличивается для разных cpp. Иногда проще снести и, да, потом возможно написать снова
Записан
Akon
Гость
« Ответ #7 : Май 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() и т.п. дают ненулевой релизный оверхэд.
« Последнее редактирование: Май 14, 2012, 15:34 от Akon » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 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
 
Записан
Akon
Гость
« Ответ #9 : Май 14, 2012, 16:40 »

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

Цитировать
Но далеко не всегда печать ложится в 1 строку, напр
Полностью согласен.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Май 14, 2012, 18:22 »

С отловом фатальных ошибок все довольно неплохо - макрос разворачивается в assert, и все дела. Однако гораздо чаще надо печатать (многочисленные) данные на этапе выполнения чтобы осознать а что же происходит и почему результат не соответствует ожидаемому (хотя ничто не вылетает). Пользуюсь примитивным #if, здесь мне добавить нечего. Самому хотелось бы узнать о более тонких методах/подходах
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.103 секунд. Запросов: 23.