Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Общие вопросы _ Странный #define, требуется пояснение

Автор: hkarel 27.11.2009, 16:10

Здравствуйте.
Изучая потроха Qt наткнулся на такую запись:

# define Q_DECLARE_INTERFACE(IFace, IId) Q_DECLARE_INTERFACE(IFace, IId)

Вопрос: зачем в теле макроса повторять его наименование? Какой а этом смысл?
Почему бы просто не записать
# define Q_DECLARE_INTERFACE(IFace, IId)

?

Автор: Litkevich Yuriy 27.11.2009, 18:58

Просто вместо макроса будет подставлен он же (это используется для обработки MOC'ом, что видно из окружающего дефайна)

А если MOC не запущен (т.е. файл обрабатывает не он), то будет так:

#ifndef Q_MOC_RUN
#  define Q_DECLARE_INTERFACE(IFace, IId) \
    template <> inline IFace *qobject_cast_helper<IFace *>(QObject *object, IFace *) \
    { return (IFace *)(object ? object->qt_metacast(IId) : 0); } \
    template <> inline IFace *qobject_cast_helper<IFace *>(const QObject *object, IFace *) \
    { return (IFace *)(object ? const_cast<QObject *>(object)->qt_metacast(IId) : 0); }
#endif // Q_MOC_RUN

Автор: DIMEDROLL 27.11.2009, 19:17

Цитата(Litkevich Yuriy @ 27.11.2009, 17:58) *
Просто вместо макроса будет подставлен он же (это используется для обработки MOC'ом, что видно из окружающего дефайна)

А зачем его тогда вообще дефайнить если он уже продефайнен?
Что будет если его непродефайнить?
Как заработать миллион? :-)

Почему не написать так:
#ifdef Q_MOC_RUN
#  define Q_DECLARE_INTERFACE(IFace, IId)
# else
#  define Q_DECLARE_INTERFACE(IFace, IId) \
    bla bla bla...
#endif // Q_MOC_RUN

Автор: niXman 27.11.2009, 19:39

Цитата(DIMEDROLL @ 27.11.2009, 19:17) *
Почему не написать так

Спроси у троллей.

Автор: Litkevich Yuriy 27.11.2009, 20:21

DIMEDROLL, когда работает препроцессор, то он вместо макроса подставлет его тело, если тела нет, то он ничего неподставит, т.е.
До препроцессора было:

#define FIRST(A, B)
#define SECOND(A, B) THERD(A, B)

// Далее по коду
FIRST(X, Y);
SECOND(X, Y)
после перпроцессора
//препроцессорных директив больше нет, они разрешены
// Далее по коду

THERD(X, Y)

Автор: DIMEDROLL 27.11.2009, 20:32

Цитата(Litkevich Yuriy @ 27.11.2009, 19:21) *
DIMEDROLL, когда работает препроцессор, то он вместо макроса подставлет его тело, если тела нет, то он ничего неподставит, т.е.

Да, я представляю как работает препроцессор. Но судя по коду идет так:
#ifndef Q_MOC_RUN
#  define Q_DECLARE_INTERFACE(IFace, IId) \
    template <> inline IFace *qobject_cast_helper<IFace *>(QObject *object, IFace *) \
    { return (IFace *)(object ? object->qt_metacast(IId) : 0); } \
    template <> inline IFace *qobject_cast_helper<IFace *>(const QObject *object, IFace *) \
    { return (IFace *)(object ? const_cast<QObject *>(object)->qt_metacast(IId) : 0); }
#endif // Q_MOC_RUN

# define Q_DECLARE_INTERFACE(IFace, IId) Q_DECLARE_INTERFACE(IFace, IId)

Выходит что если Q_MOC_RUN НЕ определен, то получим шаблон. Если определен, то что получим?

Автор: Litkevich Yuriy 27.11.2009, 20:52

Цитата(DIMEDROLL @ 27.11.2009, 23:32) *
Если определен, то что получим?
подстановку тела макроса, а телом является строка:
Q_DECLARE_INTERFACE(IFace, IId), в которую препроцессор ещё воткнёт аргументы и того получим:
Q_DECLARE_INTERFACE(IFace, IId)

Автор: DIMEDROLL 27.11.2009, 21:34

Цитата(Litkevich Yuriy @ 27.11.2009, 19:52) *
подстановку тела макроса, а телом является строка:
Q_DECLARE_INTERFACE(IFace, IId), в которую препроцессор ещё воткнёт аргументы и того получим:
Q_DECLARE_INTERFACE(IFace, IId)

тогда будет ошибка: идентификатор Q_DECLARE_INTERFACE не найден, вот код:
#define MOC

#ifndef MOC
#define EQUAL(A,B) (A)==(B)
#endif

#define EQUAL(A,B) EQUAL(A,B)

void main() {
    int a = 3;
    int b = 3;
    bool f = EQUAL(a,b);
}

error C3861: 'EQUAL': identifier not found
ошибка же и тогда если закоментировать первую строку
updated:
Глянул в исходниках кьют, теперь понятно :)
макрос то был не просто обьявлен, а с ифдефом тоже:
//#define MOC

#ifndef MOC
#define EQUAL(A,B) (A)==(B)
#else
#define EQUAL(A,B) EQUAL(A,B)
#endif



void main() {
    int a = 3;
    int b = 3;
    bool f = EQUAL(a,b);
}

Тоесть как правильно было сказано во втором посте, максрос
# define Q_DECLARE_INTERFACE(IFace, IId) Q_DECLARE_INTERFACE(IFace, IId)

предназначен для MOC компилятора(или препроцессора, как там его называют...)

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)