Объединение расширенного макроса и слова с использованием препроцессора Fortran - программирование

Объединение расширенного макроса и слова с использованием препроцессора Fortran

Я пытаюсь конкатенировать слово в исходном коде с расширением макроса препроцессора. В основном у меня есть 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 в той же строке. Я подозреваю, что это особенность "традиционного" препроцессора C...

4b9b3361

Ответ 1

Я провел некоторое исследование, и кажется, что в большинстве случаев большинство компиляторов Fortran (например, Intel и PGI) используют относительно обычный C-препроцессор с оператором маркировки токенов. Нам нужна только специальная обработка для gfortran, которая использует препроцессор C в традиционном режиме без оператора маркера.

Благодаря записи на c-faq.com я нашел это определение макроса CAT, который работает со всеми тестируемыми компиляторами пока:

#ifdef __GFORTRAN__
#define PASTE(a) a
#define CAT(a,b) PASTE(a)b
#else
#define PASTE(a) a ## b
#define CAT(a,b) PASTE(a,b)
#endif

Другое решение (которое все еще использует трюк /**/) было опубликовано Джонатаном Леффлером в этом ответе к соответствующему вопросу.