Я пытаюсь соединить слово в исходном коде с расширением макроса препроцессора. По сути, у меня где-то в коде есть foo
, а с #define EXPANSION bar
я хочу получить foobar
. Однако я изо всех сил пытаюсь найти способ сделать это, который работает со всеми компиляторами. На данный момент я был бы счастлив, если бы это работало с gfortran и ifort.
Согласно его документации, препроцессор gfortran является Препроцессор C, работающий в «традиционном режиме», не имеет оператора вставки токена ##
. Однако тот же эффект можно получить с пустым комментарием /**/
в стиле C. Препроцессор ifort ведет себя как обычный препроцессор C, поэтому обычная вставка токенов делает свое дело в ifort. К сожалению, пустой комментарий /**/
не работает в ifort, так как вместо этого комментарий заменяется одним пробелом.
Вот небольшой пример:
#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y
foo/**/EXPANSION
CAT(foo,EXPANSION)
Для чего gfortran производит:
foobar
foo ## bar
В то время как ifort дает мне:
foo bar
foobar
Конечно, я мог выбрать правильный путь, проверив предопределенные макросы для обоих компиляторов:
#ifdef __GFORTRAN__
foo/**/EXPANSION
#else
CAT(foo,EXPANSION)
#endif
Это работает для них обоих, но довольно некрасиво иметь препроцессор условным для каждого расширения. Я бы предпочел избежать этого и использовать магию макросов только один раз в начале.
Я видел этот ответ на другой вопрос, который, вероятно, позволил бы мне обойти эту проблему, но я предпочел бы найти решение, которое не вызывает препроцессор отдельно.
Я не слишком знаком с препроцессором C. Может быть, есть простой способ сделать то, что я хочу. Есть идеи?
EDIT: я уже пробовал что-то вроде этого:
#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#ifdef __GFORTRAN__
#define PASTE(x,y) x/**/y
#else
#define PASTE(x,y) x ## y
#endif
CAT(foo,EXPANSION)
К сожалению, это не работает в gfortran, где выдается fooEXPANSION
. Я не совсем уверен, как это работает, но, видимо, расширение макроса CAT
предотвращает расширение EXPANSION
в той же строке. Подозреваю, что это особенность "традиционного" препроцессора Си...
CONCAT
, которая зависит от компилятора. Это можно использовать для всех расширений. Подробнее см. этот ответ. - person d_1999   schedule 20.12.2016x/**/y
производитfooEXPANSION
, но `x/**/y` производитfoo bar
. Я рекомендую сформулировать вопрос так, чтобы он привлек внимание экспертов по препроцессорам C, и они не пропустили его, потому что они подумали бы, что он специфичен для Fortran (а это не так). - person Vladimir F   schedule 20.12.2016CAT
происходит первым, производяfooEXPANSION
. В этом случае словоEXPANSION
не будет расширено, так как оно не разделено пробелом. Если вы поместите дополнительный пробел передy
, расширениеCAT
дастfoo EXPANSION
, которое будет расширено доfoo bar
. - person Robert Rüger   schedule 21.12.2016