Макропроцессор препроцессора C - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть демостративный код ниже.Я ожидаю, что результатом будет инициализированный массив.

#define _NAME name
#define CFIT(name)\
    { _NAME },

const char * idns[] = {
    CFIT("address")
    CFIT("device_id")
    CFIT("device_bh")
    CFIT("device_hw")
    CFIT("device_fw")
    "" };

... но препроцессор создаст это:

const char * idns[] = {

    { name },
    { name },
    { name },
    { name },
    { name },
    ""
};

Удивительно, но препроцессор C ++ работает так, как ожидалось.Замените макрос _NAME на токен 'name', который также работает напрямую.Есть намеки?Используя 32b mingw 5.3.0.

1 Ответ

0 голосов
/ 07 декабря 2018

Давайте рассмотрим только один вызов;Я выберу это:

CFIT("address")

Препроцессор сначала выполняет подстановку аргументов .На этом этапе, если параметр (name) находится в списке замены ({ _NAME },; здесь я просто зачищаю пробелы), а не зашифрован или не участвует в вставке, то аргумент полностью раскрывается, и результатызаменяются на параметр.Здесь name не появляется в этом списке замены, так что ничего не поделаешь.Таким образом, после подстановки аргумента у вас есть { _NAME },.

Следующим шагом будет повторное сканирование и дальнейшая замена (после выполнения строкового преобразования и вставки, которых нет).На этом этапе оставшиеся токены повторно сканируются, чтобы макросы могли расширяться (после синей окраски текущего макроса, но это не имеет никакого эффекта).На этом этапе _NAME распознается как объектоподобный макрос, поэтому его расширение начинается.Случается, что это расширяется до name, но мы уже закончили с подстановкой аргументов, поэтому он не имеет отношения к параметру name на данный момент ... это просто еще один токен.

...