Развернуть часть токена препроцессора - PullRequest
2 голосов
/ 11 апреля 2011

Препроцессор C разбивает исходный текст на токены и выполняет только расширения, соответствующие этим токенам.Обычно это ожидаемое поведение, но иногда нет.

Возьмите этот пример, я хотел бы реализовать некоторую функциональность, подобную шаблону, хорошим способом.Обычно это реализовано так:

#define add_function_template(mytype) \
    mytype add_##mytype(mytype a, mytype b) { \
        return a + b; \
    }

Оператор конкатенации ## расширяет это, но необходимость заключать в кавычки всю функцию с обратной косой чертой очень громоздко.Можно ли как-то сделать подобное расширение для имени функции вне тела макроса?

Например, что-то вроде

#define TYPENAME int
TYPENAME add_TYPENAME(TYPENAME a, TYPENAME b) {
    return a + b;
}

Идентификатор add_TYPENAME не раскрывается, остальное -.Нет, как я могу расширить такие идентификаторы?Вспомогательные макросы тоже были бы в порядке, но я не могу найти какой-либо разумный способ ...

Ответы [ 3 ]

4 голосов
/ 11 апреля 2011

Вы не можете сделать это с препроцессором C.Токены предварительной обработки (например, add_TYPENAME) не могут быть разделены.Самое простое «решение» немного уродливо:

#define CONCAT_IMPL(x, y) x ## y
#define CONCAT(x, y) CONCAT_IMPL(x, y)
#define MAKE_TYPENAME_FUNCTION_NAME(x) CONCAT(x, TYPENAME)

TYPENAME MAKE_TYPENAME_FUNCTION_NAME(add_)(TYPENAME a, TYPENAME b) {

необходимость заключать в кавычки всю функцию с обратной косой чертой очень громоздкано это стоимость использования препроцессора для чего-то нетривиального.

2 голосов
/ 11 апреля 2011

Вы не можете сделать это.Подумайте, как бы он испортил свой код.

#define p f

printf () расширится как frintf ()

или #define . ,

и так далее ...

0 голосов
/ 11 апреля 2011

Вы можете достичь того, что хотите, если вы хотите #include файла .c из другого файла .c.

Вот пример того, как вы это сделаете:

В add_function_template.c:

#define add_function(t) t add_##t(t a, t b)  // This line could be moved elsewhere.
add_function(mytype)
{
    return a + b;
}

In footype.c:

#define mytype footype
#include <add_function_template.c>
...