crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Странный #define, требуется пояснение
hkarel
  опции профиля:
сообщение 27.11.2009, 16:10
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 25
Регистрация: 25.5.2009
Пользователь №: 771

Спасибо сказали: 0 раз(а)




Репутация:   0  


Здравствуйте.
Изучая потроха 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
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Просто вместо макроса будет подставлен он же (это используется для обработки 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
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

Спасибо сказали: 23 раз(а)




Репутация:   0  


Цитата(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
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 169
Регистрация: 18.6.2008
Пользователь №: 204

Спасибо сказали: 1 раз(а)




Репутация:   0  


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

Спроси у троллей.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.11.2009, 20:21
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


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
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

Спасибо сказали: 23 раз(а)




Репутация:   0  


Цитата(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
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DIMEDROLL @ 27.11.2009, 23:32) *
Если определен, то что получим?
подстановку тела макроса, а телом является строка:
Q_DECLARE_INTERFACE(IFace, IId), в которую препроцессор ещё воткнёт аргументы и того получим:
Q_DECLARE_INTERFACE(IFace, IId)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DIMEDROLL
  опции профиля:
сообщение 27.11.2009, 21:34
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

Спасибо сказали: 23 раз(а)




Репутация:   0  


Цитата(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 компилятора(или препроцессора, как там его называют...)

Сообщение отредактировал DIMEDROLL - 27.11.2009, 21:48
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 22:57