Устранение скобок Stringification

В c у меня есть следующее в существующей базе кода:

#define MYVAR (1)

Как вы можете видеть, это соответствует хорошей практике в C, заключая #define в круглые скобки (хотя я знаю, что в этом случае это не имеет значения, поскольку значение не является выражением). Независимо от того, я хотел бы использовать это в stringification. когда я делаю это:

#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY(x)

const char* mystring = TO_STRING(MYVAR) ;

Результирующая строка — «(1)». Я хотел бы убрать круглые скобки без простых действий:

#define MYVAR 1

Есть ли способ устранить круглые скобки во время стробирования в c?


person David Mokon Bond    schedule 26.08.2013    source источник
comment
Поскольку это находится на этапе предварительной обработки, и вы явно определили MYVAR как замененные на (1), я не верю, что то, что вы ищете, выполнимо. Если это так, я не могу себе представить, чтобы это было так, не будучи очень специфичным для cpp-backend.   -  person WhozCraig    schedule 26.08.2013
comment
Я боялся этого. Спасибо   -  person David Mokon Bond    schedule 26.08.2013
comment
Я не считаю, что окружающие литералы скобками обязательно являются хорошей практикой, это может даже привести к тому, что кто-то поверит, что это часть синтаксиса макроса.   -  person Veltas    schedule 26.08.2013
comment
@Veltas Это очень распространенная практика, отчасти позволяющая избежать случайных побочных эффектов от макрорасширений. Во-первых, я не сторонник сложных макросов препроцессора, но для обеспечения раскрытия значений, а не ссылок на, это не только распространено, но и рекомендуется. (не помогает ОП, но все же верно).   -  person WhozCraig    schedule 26.08.2013
comment
@Veltas Я не уверен, что понимаю твой вопрос. Но простой пример: возьмем #define MUL(x,y) ((x)*(y)) и просто #define MUL(x,y) x*y. Что происходит, когда это расширяется с помощью MUL(a+1,b+2) ? Последний становится a+1*b+2, что, конечно, не всегда ((a+1)*(b+2)). Скобки нужны просто для того, чтобы подавить такое непреднамеренное расширение, чтобы изолировать предполагаемую оценку параметра, если хотите.   -  person WhozCraig    schedule 26.08.2013
comment
Является ли MYVAR всегда целым числом?   -  person Jiminion    schedule 26.08.2013
comment
@WhozCraig: я говорил о литералах. То, что это обычная практика, не означает, что это хорошая практика. Я не уверен, что вижу смысл заключать литералы в квадратные скобки в определениях макросов, это просто кажется громоздким.   -  person Veltas    schedule 26.08.2013
comment
@Veltas В общем, я считаю, что лучше всего делать это даже для литералов, потому что, если у вас нет, через 3 года неизбежно появится младший кодер, измените свой макрос на #define MYVAR 1 + 1 без добавления параграфов. а затем... Но, как и в случае с большинством стилевых вещей, это обсуждается... просто мое мнение.   -  person David Mokon Bond    schedule 26.08.2013
comment
Хорошая практика состоит в том, чтобы делать что-то по какой-то причине, знать, что это за причина, и по этой причине иметь отношение к тому, что вы делаете. Таким образом, использование скобок здесь является не хорошей практикой: это само определение плохой практики, препятствующей размышлениям о том, что вы делаете. Если появится новый кодер и сделает это позже... наймите лучших новичков.   -  person Leushenko    schedule 29.08.2013


Ответы (1)


Просто используйте STRINGIFY x вместо STRINGIFY(x)

#include <stdio.h>

#define MYVAR 1

#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY x

int main(void)
{
    const char *mystring = TO_STRING(MYVAR);

    printf("%s\n", mystring);
    return 0;
}

TO_STRING(x) расширяется до STRINGIFY (1), когда MYVAR определяется как (1)

Если MYVAR определяется как 1 без круглых скобок, вы получаете ошибку времени компиляции.

person David Ranieri    schedule 26.08.2013
comment
Я подтвердил, что это работает, но не могли бы вы немного объяснить? например зачем нам нужен каждый из этих шагов. - person David Mokon Bond; 26.08.2013