Что означает "#define STR (a) #a"?

Я читаю исходный код телефона. Это реализация FOSS JavaME. Это написано на С++, и я наткнулся на это:

// Makes a string of the argument (which is not macro-expanded)
#define STR(a) #a

Я знаю C и С++, но я никогда не читал что-то вроде этого. Что делает # in #a?

Кроме того, в том же файле есть:

// Makes a string of the macro expansion of a
#define XSTR(a) STR(a)

Я имею в виду, что использование определения нового макроса, если все это происходит, - это вызов существующего макроса?

Исходный код находится в https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view=markup. Вы можете найти его с помощью CTRL + F.

Ответ 1

В первом определении #a означает печать макроса в виде строки. Это повернетс, например. STR(foo) в "foo", но он не будет делать макроразложение по своим аргументам.

Второе определение ничего не добавляет к первому, но, передавая его аргумент другому макросу, оно полностью расширяет макрос его аргумента. Таким образом, XSTR(expr) создает строку expr со всеми полностью расширенными макросами.

Ответ 2

# - оператор стробирования. Препроцессор выводит строку из параметра.

Скажите, что у вас есть:

STR(MyClass);

Он будет предварительно обработан как:

"MyClass";

Уровень косвенности (с использованием XSTR()) связан с правилами макрораспределения.

Ответ 3

#a называется оператор стримера. Он принимает формальный параметр, в данном случае a, и превращает его в строку, заключая его в двойные кавычки.

Итак, если у вас есть:

string s = STR("my quoted string");
cout << s;

Вывод будет:

"my quoted string"

Ответ 4

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

Вторая используется, чтобы вызвать макрораспределение аргумента. Вы обычно используете их что-то вроде этого:

#define a value_a

printf("%s", XSTR(a));

Расширение макроса расширит a до string_a, а stringify превратит это в строку, поэтому вывод будет value_a.