g++ макросы

Serab

Боян, наверное, но меня удивило. Подскажите, почему

#define __WFILE__ L ## __FILE__

не клеится, а

#define WIDEN(x) L ## x
#define __WFILE__ WIDEN(__FILE__)

клеится?
Конкретный контекст — что-то типа

... L"<" __WFILE__ L">"

Maurog

в первом случае переменную клеют, во втором - ее значение :grin:

Serab

Да уж :)
Значит я в первый раз где-то еще налажал в макросах, потому что было какое-то непонятное сообщение об ошибке. А тут-то действительно ясно все :crazy:

Maurog

тут-то действительно ясно все
ответил машинально, где-то слышал звон
а сам не понимаю :grin:

Serab

ну препроцессор работает перед компилятором, в первом случае компилятор получает на вход L__WFILE__, не находит по понятным причинам символ и шлет нах.
Во втором получается WIDEN(__FILE__ раскрывается __FILE__, получается WIDEN("SomeFile.cpp" потом L"SomeFile.cpp" и все пучком.

slonishka

прочитай boost::preprocessor и поймешь, что происходит на самом деле.

Serab

Круто. Вы этим пользуетесь "там у себя"?

Serab

Ну да, я понял, к чему ты, что постепенно ничего не раскрывается, да, это понятно, иначе были бы неоднозначности во всяких #define new DEBUG_NEW, #define DEBUG_NEW new... Просто не всегда можно сразу понять сложную вещь, физику тоже сначала нерелятивистскую проходят...

slonishka

я только недавно начал пытаться где-то разумно использовать такие техники,
сильно упрощая свою версию по сравнению с кодом из boost::preprocessor.
а vozbu макросов избегает, как правило.
вообще, они в некоторых специфических случаях очень удобны и такой случай
довольно сложно самому первым выдумать, поэтому чаще всего удачно удается
применить что-то, прочитанное в каком-то другом существующем коде.

slonishka

Ну да, я понял, к чему ты, что постепенно ничего не раскрывается, да, это понятно, иначе были бы неоднозначности во всяких #define new DEBUG_NEW, #define DEBUG_NEW new... Просто не всегда можно сразу понять сложную вещь, физику тоже сначала нерелятивистскую проходят...
по-моему, это нормально. такие макросы трудно пишутся даже для одного, заранее известного препроцессора.

slonishka

еще хорошая техника, использование которой в boost::preprocessor
сильно во все обернуто, поэтому видно с трудом.
#define MYOPTS(_, ...) \
_(opt1, arg1, ##__VA_ARGS__) \
_(opt2, arg2, ##__VA_ARGS__) \
...

#define MYCALL(opt, arg, ...) \
...

MYOPTS(MYCALL, various other args)

slonishka

синтаксис, к сожалению, отвратительный.
ну и семантика.
по мне, лучше, конечно, код генерить.
ну там свой препроцессор написать, к примеру.
если делать нечего.

rosali

объяснение клевое, только проблема в том, что __FILE__ интерпретируется тоже препроцессором после раскрытия include-ов компилятор уже не разберется какие там файлы были.

Serab

И какая тут "проблема"?
__FILE__ я вообще написал для упрощения, у меня там был другой символ, который я дефайнил
Оставить комментарий
Имя или ник:
Комментарий: