Передача значения переменной в макрос в C - PullRequest
6 голосов
/ 16 февраля 2011

Я пытаюсь передать значение переменной макросу в C, но я не знаю, возможно ли это.Пример:

#include <stdio.h>

#define CONCVAR(_n) x ## _n

int main () {
   int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
   int i;

   for (i = 0; i <= 9; i++) CONCVAR(i) = i*5;

   return 0;
}

Здесь я пытаюсь использовать макрос для присвоения значения всем переменным x_, используя ## токены.Я знаю, что могу легко добиться этого с массивами, но это только для целей обучения.

CONCVAR(i) заменяется на xi, а не x1 (если i == 1).Я знаю, как определяются и работают макросы, все дело в подстановке, но я хочу знать, возможно ли передать значение i вместо буквы i в макрос.

Ответы [ 3 ]

13 голосов
/ 16 февраля 2011

Подстановка значения i в макрос невозможна, поскольку подстановка макросов происходит до компиляции кода. Если вы используете GCC, вы можете увидеть выходные данные препроцессора, добавив аргумент командной строки '-E' (заметьте, однако, что вы увидите все # include, вставленные в ваш код.)

C - статический язык, и вы не можете определять имена символов во время выполнения. Однако то, что вы пытаетесь достичь, возможно, если вы используете массив и ссылаетесь на элементы с помощью индексов. Как правило, если у вас много переменных, таких как x0, x1 и т. Д., Вам, вероятно, следует использовать контейнер в виде массива.

9 голосов
/ 16 февраля 2011

Нет, поскольку значение из i существует только в время выполнения .Расширение макроса происходит в время компиляции .

1 голос
/ 16 февраля 2011

Нет, это не сработает. Препроцессор C / C ++ - это всего лишь текстовый процессор времени «до компиляции». Таким образом, он работает с текстом, найденным как есть в вашем исходном коде.

Вот почему он берет буквальный текст «i», передает его в ваш макрос и расширяет его до буквального текста «xi» в вашем исходном коде. Затем это передается в компилятор. Затем компилятор начинает синтаксический анализ постобработанного текста, находя буквенный токен "xi" как необъявленную переменную, и в процессе набирает обороты.

Вы можете взять ваш пример исходного кода и передать его компилятору gcc (например, я использовал gcc под cygwin, вставляя ваш код в файл с именем pimp.c из-за отсутствия лучшего имени) , Тогда вы получите следующее:

$ gcc pimp.c
pimp.c: In function `main':
pimp.c:9: error: `xi' undeclared (first use in this function)
pimp.c:9: error: (Each undeclared identifier is reported only once
pimp.c:9: error: for each function it appears in.)

Короче говоря, нет, вы не можете этого сделать. Чтобы иметь возможность сделать это, препроцессор должен выступать в роли переводчика. C и C ++ (как правило) не являются интерпретируемыми языками, и препроцессор не является интерпретатором. Мое предложение состоит в том, чтобы очень четко понять различия между компиляторами и интерпретаторами (и между компилируемыми и интерпретируемыми языками.)

Привет.

...