Заменить строку в макропеременной? - PullRequest
1 голос
/ 28 октября 2010

У меня есть макрос, в котором я передаю аргумент и использую его, определяющий новую переменную на основе имени ввода:

#define DO_X(x) char _do_x_var_ ## x; /* other things */

Проблема в том, что если я передаю переменную структуры, она ломается:

DO_X(some_struct->thing)

становится:

char _do_x_var_some_struct->thing; /* other things */

РЕДАКТИРОВАТЬ: То, что я хочу, чтобы это было оценено:

char _do_x_var_some_struct__thing; /* other things */

(или любое допустимое имя переменной, содержащее что-то подобноена вход)

То, что я на самом деле хочу, чтобы это работало:

#define DO_X(x) for(char _do_x_var_ ## x; /*things*/)
DO_X(x){
    DO_X(y) {
        /*things*/
    }
}

DO_X(object->x){
    DO_X(object->y) {
        /*things*/
    }
}

, но чтобы это не сработало:

#define DO_X(x) for(char _do_x_var_ ## x; /*things*/)
DO_X(x){
    DO_X(x) { // <-- multiple definition of _do_x_var_x
        /*things*/
    }
}

DO_X(object->x){
    DO_X(object->x) { // <-- multiple definition of _do_x_var_object__x (or whatever)
        /*things*/
    }
}

Есть ли способ сделатьэта работа?Может быть, заменить -> на __ или что-то?Я нашел способы объединить, но не заменить строки ..

Ответы [ 2 ]

4 голосов
/ 28 октября 2010

Вы не нашли способ переписать произвольные строки, потому что макросы не могут этого сделать.Имена макросов должны быть действительными идентификаторами, а -> - нет.Препроцессор C очень ограничен в том, что он может делать.Вы могли бы заглянуть в m4 для более сильного препроцессора, но, вероятно, вы пошли по неверному пути.

2 голосов
/ 28 октября 2010

Я не знаю ни одного механизма препроцессора для обработки параметра struct-> element как двух отдельных токенов или для автоматического преобразования -> в подчеркивание. Мое предложение состоит в том, чтобы иметь отдельный макрос, например DO_X2 (struct_ptr, element), который добавил бы «->» или «_», где это необходимо. Тогда вы можете использовать DO_X или DO_X2 в зависимости от ситуации.

Существует отдельная проблема, если вы планируете использовать эти макросы, как указано. Внутренний цикл for может объявлять одно и то же имя переменной, и это не будет считаться ошибкой, поскольку они имеют различную область видимости. Например, если предположить, что ваш компилятор C поддерживает объявление итератора в операторе for следующим образом (что я не считаю стандартным поведением для C):

for (int i=0; i<10; ++i)

Тогда вы можете сделать следующее, и это не будет считаться ошибкой:

int sum = 0;
for (int i=0; i<10; ++i)
    for (int i=0; i<10; ++i)
        ++sum;

Два "int i" имеют различную область видимости, поэтому они должны прекрасно компилироваться и выполняться.

...