Код
#define STX_PORT STX_CONCAT(PORT,STX_PORT_NAME)
Error[Pe020]: identifier "PORTSTX_PORT_NAME" is undefined D:\step_f\step_f.c 59
Не доходит до меня ... почему это не работает?
Даю я ему два параметра ... оператору ## должны придти две лексемы PORT и B
Почему не раскрывается значение STX_PORT_NAME и надо городить
Код
#define STX_CONCAT(a,b) a ## b
#define STX_GEN_PORT(name) STX_CONCAT(PORT,name)
#define STX_PORT STX_GEN_PORT(STX_PORT_NAME)
____
P.S.
Пропустил ответ zltigo. Ушёл читать
Упустил я сей момент в свое время у Кернигана...
http://masterpc.alfaspace.net/books/CCScie...amming/a/#a12_3Цитата
Если макроопределение было задано вторым способом, то текстовая последовательность, состоящая из его идентификатора, возможно, со следующими за ним символами-разделителями, знака (, списка лексем, разделенных запятыми, и знака ), представляет собой вызов макроса. Аргументами вызова макроса являются лексемы, разделенные запятыми (запятые, "закрытые" кавычками или вложенными скобками, в разделении аргументов не участвуют). Аргументы при их выделении макрорасширениям не подвергаются. Количество аргументов в вызове макроса должно соответствовать количеству параметров макроопределения. После выделения аргументов окружающие их символы-разделители выбрасываются. Затем в замещающей последовательности лексем макроса идентификаторы-параметры (если они не закавычены) заменяются на соответствующие им аргументы. Если в замещающей последовательности перед параметром не стоит знак # и ни перед ним, ни после него нет знака ##, то лексемы аргумента проверяются: не содержат ли они в себе макровызова, и если содержат, то прежде чем аргумент будет подставлен, производится соответствующее ему макрорасширение.
На процесс подстановки влияют два специальных оператора. Первый -это оператор #, который ставится перед параметром. Он требует, чтобы подставляемый вместо параметра и знака # (перед ним) текст был заключен в двойные кавычки. При этом в строковых литералах и символьных константах аргумента перед каждой двойной кавычкой " (включая и обрамляющие строки), а также перед каждой обратной наклонной чертой \ вставляется \.
Второй оператор записывается как ##. Если последовательность лексем в любого вида макроопределении содержит оператор ##, то сразу после подстановки параметров он вместе с окружающими его символами-разделителями выбрасывается, благодаря чему "склеиваются" соседние лексемы, образуя тем самым новую лексему. Результат не определен при получении неправильных лексем или когда генерируемый текст зависит от порядка применения операторов ##. Кроме того, ## не может стоять ни в начале, ни в конце замещающей последовательности лексем.
Это здесь ... но надо вникнуть ...
Заготовка для примера.
Код
#define STX_PORT_NAME B
#define STX_PIN 3
#define STX_PORT_(name) PORT ## name
#define STX_PORT__(name) STX_PORT_(name)
#define STX_PORT STX_PORT__(STX_PORT_NAME)
Код
STX_PORT_(STX_PORT_NAME) |= (1<<STX_PIN);
Получаем
Error[Pe020]: identifier "PORTSTX_PORT_NAME" is undefined D:\step_f\step_f.c 84
Ибо! STX_PORT_NAME, как параметр, передается в
#define STX_PORT_(name) PORT ## name,
а там возле name стоит ## и превращения STX_PORT_NAME => B не происходит.
Код
STX_PORT__(STX_PORT_NAME) |= (1<<STX_PIN);
Всё скомпилилось
Ибо! В макросе
#define STX_PORT STX_PORT__(STX_PORT_NAME)
нет ## и STX_PORT_NAME превратилось в B
дальше идет вызов #define STX_PORT__(name) с значением параметра уже B, а не STX_PORT_NAME ...
и дальше по накатанной.
И в итоге получил вот такое:
Код
#define STX_PORT_NAME B
#define STX_PIN 3
#define STX_CONCAT(a,b) a ## b
#define STX_CONCAT2(a,b) STX_CONCAT(a,b)
#define STX_PORT STX_CONCAT2(PORT,STX_PORT_NAME)
#define STX_DDR STX_CONCAT2(DDR,STX_PORT_NAME)
#define stx_init() {STX_PORT |= (1<<STX_PIN);\
STX_DDR |= (1<<STX_PIN);}