Russian Qt Forum

Qt => Общие вопросы => Тема начата: SASA от Октябрь 09, 2008, 19:00



Название: Издержки метообъектной информации.
Отправлено: SASA от Октябрь 09, 2008, 19:00
   Иногда я сталкиваюсь с такой проблемой при использовании connect( ): существование сигналов и слотов с соответствующими параметрами не проверятся на этапе компиляции. Поэтому, при изменении сигнатуры этих функций могут появиться скрытые ошибки. Я придумал такой выход:
Код:
Q_ASSERT(connect(obj1,SIGNAL(signal(int)),obj2,SLOT(slot(int))))
Это полностью не исключает ситуации описанной выше, но шансов "напороться" на эту ошибку становится больше.
Аналогично поступаю и с QMetaObject::invokeMethod().
Код:
Q_ASSERT(QMetaObject::invokeMethod(obj,"method",Q_ARG(QString,str))).
   При работе с проперти по имени (пример: obj.property("prop")) тоже может возникнуть ошибка при смене имени проперти или его типа. Поэтому для взятия значения я написал функцию, которая при отсутсвии свойства или неправельном типе вывалит ассерт. Вызов функции setProperty() тоже обкладываю ассертом.
   
   Собственно вопрос (или тема для дискуссии) А нормальное ли это решение? Может кто-то борется с этим по-другому.

P.S. Приветствую любые высказывания по теме.


Название: Re: Издержки метообъектной информации.
Отправлено: pastor от Октябрь 09, 2008, 19:54
Очень интересное решение!


Название: Re: Издержки метообъектной информации.
Отправлено: Rcus от Октябрь 09, 2008, 20:16
В релизном режиме макрос Q_ASSERT раскрывается в пустое выражение, поэтому скорее следует определить что-нибудь типа такого макроса
#ifdef QT_NO_DEBUG
#define CUSTOM_ASSERT(x) x
#else
#define CUSTOM_ASSERT(x) Q_ASSERT(x)
#endif


Название: Re: Издержки метообъектной информации.
Отправлено: Alex03 от Октябрь 10, 2008, 08:39
А зачем всё это?
В дебаге connect() и так матерится в отладочную консоль.


Название: Re: Издержки метообъектной информации.
Отправлено: ритт от Октябрь 10, 2008, 08:43
в релизе - тоже )


Название: Re: Издержки метообъектной информации.
Отправлено: Rcus от Октябрь 10, 2008, 08:54
connect() - пишет, invokeMethod() - нет, а проверять результат выполнения обеих операций надо, так не лучше ли делать это единообразно?
*shrug* у меня правда и вызовы QSqlQuery::exec() обернуты в макрос, выполняющий проверку возвращаемого результата и в случае ошибки выводящий Q_FUNC_INFO, текст запроса и boundValues


Название: Re: Издержки метообъектной информации.
Отправлено: ритт от Октябрь 10, 2008, 09:22
а вот на _эти_ макросы я взглянул бы :)
самому лениво коряжиться...


Название: Re: Издержки метообъектной информации.
Отправлено: Rcus от Октябрь 10, 2008, 09:44
Код:
#ifdef QT_NO_DEBUG
#define Q_EXEC(q) {q.exec();}
#else
#define Q_EXEC(q) { \
if (!q.exec()) \
{ \
QMap<QString,QVariant> bv = q.boundValues(); \
QString sbv; \
for(typeof(bv)::const_iterator i = bv.constBegin(); \
i != bv.constEnd(); ++i) \
sbv += i.key() + ":=" + i.value().toString() + "\n"; \
qFatal("Query failed in function:%s\ntext: '%s'\nboundValues:\n%s\nreason: '%s'", \
Q_FUNC_INFO, \
qPrintable(q.lastQuery()), \
qPrintable(sbv), \
qPrintable(q.lastError().text()) \
); \
} \
}
#endif


Название: Re: Издержки метообъектной информации.
Отправлено: ритт от Октябрь 10, 2008, 10:24
о, классно...только я этот макрос лучше в отладочную QtSql запихну...не люблю свои сорцы замусоривать :)


Название: Re: Издержки метообъектной информации.
Отправлено: SASA от Октябрь 10, 2008, 14:33
Цитировать
В релизном режиме макрос Q_ASSERT раскрывается в пустое выражение
Так эти макросы нужны, чтоб отлавливать ошибки (причём явно допущенные по недосмотру, или забывчивости) в дебаге. А если они попадут в релиз, то это косяк

Ступил :-[
Цитировать
А зачем всё это?
В дебаге connect() и так матерится в отладочную консоль.

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

Цитировать
у меня правда и вызовы QSqlQuery::exec() обернуты в макрос,
Вопрос. А кто что ещё обкладывает макросами?


Название: Re: Издержки метообъектной информации.
Отправлено: Rcus от Октябрь 10, 2008, 15:07
Код:
inline void qt_noop() {}

Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line);

#if !defined(Q_ASSERT)
#  ifndef QT_NO_DEBUG
#    define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
#  else
#    define Q_ASSERT(cond) qt_noop()
#  endif
#endif
//из QtCore/qglobal.h