Подтвердить что ты не робот

Как заставить препроцессор g++ выводить новую строку в макросе?

Есть ли способ в gcc/g++ 4. * написать макрос, который расширяется на несколько строк?

Следующий код:

#define A X \ Y

Развертывается на

X Y

Мне нужно, чтобы макрос расширялся в

X
Y
4b9b3361

Ответ 1

Получил это!

#define anlb /*
*/ A /*
*/ B

anlb anlb

Стрелка вниз

gcc -E -CC nl.c

Стрелка вниз

/*
*/ A /*
*/ B /*
*/ A /*
*/ B

Ответ 2

Сделать макрос созданием специальной разметки, скажем __CR__, а затем передать результат CPP в script, который переводит макрос в истинную строку новой строки, например sed 's/__CR__/\n/g'.

Я просто нашел это полезным для создания шаблона кода, который должен быть заполнен вручную. Это легче, когда код читаем.

Ответ 3

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

#define X(y,z) y nl z

run gcc -E infile | sed g/s/nl/\n/ > whatever

(Возможно, не совсем верно, но вы поняли, правильно? Пропустите его через sed или tr или запустите Emacs на выходе.)

Я иногда использую макросы C для генерации исходного кода, и нет, я не хочу, чтобы узнать, как это сделать в Perl или M4 или еще один инструмент.

Ответ 4

Я уверен, что CPP, созданный для C, который не заботится о новых линиях, и все, не может справиться с такой работой. Тем не менее вы можете пометить нужные новые строки с помощью специальной строки маркера и передать результат через sed или awk, чтобы получить то, что вы хотите.

Ответ 5

Из docs:

в настоящей реализации, полное расширение выходит на одну строку

Ответ 6

Полагая на сторону тот факт, что неспособность ставить символы новой строки в макросах создает нечитаемый код, что затрудняет отладку выходных данных препроцессора. Верно, что C и С++ могут не заботиться о новых строках, но препроцессор C делает.

Мне бы очень хотелось создать макрос ConditionalDefine (x, y), который выводит следующее.

    #ifdef x
    #define y
    #endif

Ниже описывается что-то близкое:

    #define hash #
    #define nl
    #define _def_p8(A,B) A ifdef _P8_K60_BOARD_ A define B  A endif
    #define X_def_p8(A,B) _def_p8(A,B)
    #define def_p8(A) X_def_p8(nl hash,A)

расширяя следующее:

    def_p8(PTPD_DBGA 0)

приводит к:

    # ifdef _P8_K60_BOARD_ # define PTPD_DBGA 0    # endif

Но, не имея возможности помещать новые строки перед хэшем, он не будет работать так, как предполагалось. Это также раздражает обручи, с которыми вы должны прыгать, чтобы закрыть их.

Ответ 7

Почему имеет место интервал?

Программа imake, используемая в (старше?) сборках X11, использовала предварительный процессор C для генерации make файлов, но программа imake использовала специальную технику индикации окончаний строки с символами @@на концах строк, а затем post- обработал вывод препроцессора, чтобы заменить символы @@на символы новой строки.

Из этого проекта я пришел к выводу, что нет надежного способа получения новых строк из расширенных макросов в C (или С++). Действительно, для C нет необходимости, так как:

  • C не заботится о новых строках по сравнению с пробелом после выполнения предварительного процессора C и
  • Вы не можете генерировать предпроцессорные директивы из макросов и т.д.

Ответ 8

Это то, что вы хотите:

#define A "X \nY"