Макросы в си - gcc

Forums:

я рассмотрю здесь только следующий момент -

Stringification - "стротификация" - превращение в строку.

Иногда может потребоваться конвертировать макро-аргумент в строковую константу - параметры же не заменяются внутри строковых констант - но вы можете использовать решётку - # - специальный оператор препроцессора вместо параметра.
Когда макро-параметр используется вместе с на чинающей его решёткой например так -

#define log_struct(st, field, format, typecast) \
  log_msg("    " #field " = " #format "\n", typecast st->field)

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

Пример -

Вот макрос определённый в неком заголовочном файле log.h -
Для этого макроса используется способ определения , судя по всему,
допустимый только в gcc компиляторе - но всё же - эта штука в gcc называется
"stringification" - она вызывается при вызове макро-параметра (переданного в коде в макрос , определённый в виде функции)
в начале которого стоит символ "решётка " - #
вот пример макро0определения:

//  macro to log fields in structs.
#define log_struct(st, field, format, typecast) \
  log_msg("    " #field " = " #format "\n", typecast st->field)

Например. когда мы делаем вызов вроде:

	log_struct(fi, flags, 0x%08x, );

Макрос дополняется (расширяется) препроцессором до следующего вида:

    log_msg("    " "flags" " = " 0x%08x" "\n", fi->flags);

Что в свою очередь эквивалентно вызову функции:

    log_msg("    flags = 0x%08x\n", fi->flags);

в силу того, что в языке си производится конкатенация - сложение смежных строк.

Sometimes you may want to convert a macro argument into a string constant. Parameters are not replaced inside string constants, but you can use the `#' preprocessing operator instead. When a macro parameter is used with a leading `#', the preprocessor replaces it with the literal text of the actual argument, converted to a string constant. Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification.

There is no way to combine an argument with surrounding text and stringify it all together. Instead, you can write a series of adjacent string constants and stringified arguments. The preprocessor will replace the stringified arguments with string constants. The C compiler will then combine all the adjacent string constants into one long string.

Here is an example of a macro definition that uses stringification:

     #define WARN_IF(EXP) \
     do { if (EXP) \
             fprintf (stderr, "Warning: " #EXP "\n"); } \
     while (0)
     WARN_IF (x == 0);
          ==> do { if (x == 0)
                fprintf (stderr, "Warning: " "x == 0" "\n"); } while (0);

The argument for EXP is substituted once, as-is, into the if statement, and

Пример макроса - замена макроса функционального типа на функцию =

#define log_struct(st, field, format, typecast) \
  log_msg("    " #field " = " #format "\n", typecast st->field)
_____________________________________________
Источники(читать подробнее)=
http://www.codenet.ru/progr/cpp/Macros.php
http://gcc.gnu.org/onlinedocs/cpp/Macros...
Ключевые слова и фразы(для поиска)=