Макрос C99 для построения строкового литерала в кавычках после оценки - PullRequest
3 голосов
/ 28 июля 2010

Я разрабатываю встроенное приложение на C99, и проект содержит некоторые целочисленные константы, определенные как:

#define LEVEL1     0x0000
#define LEVEL2     (LEVEL1 + 1)

С тех пор стало полезно отслеживать эти значения для целей ведения журнала, поэтому я хотел бы использовать макрос для создания строкового литерала из оцененных версий выше. Например:

strncpy(str, STRING(LEVEL2), len);

в идеале оценивается как

strncpy(str, "0x0001", len);

или даже

strncpy(str, "0001", len);

Использование двухэтапного макроса с оператором # (как предлагает этот вопрос ) почти работает. Оценивается

strncpy(str, "(LEVEL1 + 1)", len);

Я бы хотел избежать использования функции времени выполнения - отсюда моя попытка найти решение для макроса. Предложения?

Ответы [ 2 ]

2 голосов
/ 28 июля 2010

Поскольку препроцессор-стрингер представляет собой серьезную проблему, вам необходимо добавить уровень косвенности как при создании номеров версий, так и при строковом форматировании:

#define STRING1(s) #s
#define STRING(s) STRING1(s)

#define LEVEL(x) x
#define LEVEL1 LEVEL(1)
#define LEVEL2 LEVEL(2)

printf(STRING(LEVEL2));
//2
1 голос
/ 05 августа 2010

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

Я вижу два варианта получения желаемого результата:

Ручная оценка

Напишите свои уровни в точности так, как вы хотите, чтобы они отображались, и используйте один оператор stringizer:

#define LEVEL1 0x0000
#define LEVEL2 0x0001
#define STRING(x)   # x

strncpy(str, STRING(LEVEL2), len);

Недостатком является то, что это подвержено ошибкам и может противоречить местным правилам кодирования.

Оценка времени выполнения

Используйте одну из функций форматирования строки sprintf или snprintf.

#define LEVEL1 0x0000
#define LEVEL2 0x0001

char level[7];
snprintf(level, sizeof level, "%#06x", LEVEL2);
strncpy(str, level, len);

Это накладные расходы времени выполнения, которых вы хотели избежать.

...