Есть ли способ, которым макрос может использовать значение переданного ему значения, а не сам текст определения?Подстановка подпроцессора подстановки C
Это странный пример, который, как я ожидал, был бы возможен с препроцессором.
A C файл под названием test.c
, который включает в себя два раза, чтобы определить две различные функции, которые вызываются из main
.
#ifndef IS_INDIRECT
#define IS_INDIRECT
/* int */
#define NUMTYPE int
#define PREFIX int_
#include "test.c"
#undef NUMTYPE
#undef PREFIX
/* short */
#define NUMTYPE float
#define PREFIX float_
#include "test.c"
#undef NUMTYPE
#undef PREFIX
#include <stdio.h>
int main(int argc, const char **argv)
{
printf("test int %d\n", int_squared(4));
printf("test float %f\n", float_squared(2.5));
return 0;
}
#else
/* function body */
#define fn(prefix, id) prefix ## id
NUMTYPE fn(PREFIX, squared)(NUMTYPE val)
{
return val * val;
}
#endif
дает следующее сообщение об ошибке:
In file included from test.c:18:0:
test.c:37:12: error: conflicting types for 'PREFIXsquared'
NUMTYPE fn(PREFIX, squared)(NUMTYPE val)
^
test.c:35:24: note: in definition of macro 'fn'
#define fn(prefix, id) prefix ## id
^
In file included from test.c:9:0:
test.c:37:12: note: previous definition of 'PREFIXsquared' was here
NUMTYPE fn(PREFIX, squared)(NUMTYPE val)
^
test.c:35:24: note: in definition of macro 'fn'
#define fn(prefix, id) prefix ## id
Я хотел бы иметь макрос расширить PREFIX к значению она определяется как, так что я получаю int_squared
не PREFIXsquared
Отлично, это работает. Если бы мне хотелось узнать об этом конкретном использовании препроцессора, есть ли общие термины, связанные с случаями, когда требуется макро-вызов-макрос? – ideasman42
Я не знаю об теориях, стоящих за этим трюком. В то время, когда я впервые наткнулся на эту проблему, Интернет не был настолько дружелюбен к программистам (по крайней мере, из Франции), поэтому мне пришлось разобраться в этом сам. Но K & R - это шедевр, и решение есть, если вы внимательно его прочитаете :). Я нашел [эту довольно полную и интересную статью по этому вопросу] (http://www.altdevblogaday.com/2011/07/12/abusing-the-c-preprocessor/), хотя, похоже, она не полагается на конкретную теории. –
Причина этого заключается в том, что есть предварительный сканер, который обрабатывает расширения, но второго предварительного сканирования нет. Это так, что если вложенные вызовы макросов работают. Я подозреваю, что это просто ... использование этого :). Вы можете узнать больше об этом здесь: http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan –