Странный синтаксис препроцессора C ++ - PullRequest
1 голос
/ 01 августа 2010

Я перевел мою проблему к этому фрагменту кода - но это часть более крупной программы, поэтому я не хочу другого способа сделать это - мне нужен способ сделать этим работа!

Когда я генерирую предварительно обработанный файл из этого кода:

#define OUTER(a, b) \
    a##b
#define INNER(c, d) \
    c##d

enum foo {
    OUTER(INNER(x, y), z)
}; // line 108

int APIENTRY _tWinMain(...)
{
    foo bar = xyz; // line 112
}

, я получаю:

enum foo {
    xyz
}; // line 108

int __stdcall wWinMain(...)
{
    foo bar = xyz; // line 112
}

, что я и хочу.Однако, если я пытаюсь скомпилировать код, я получаю:

ошибка C2146: синтаксическая ошибка: отсутствует '}' перед идентификатором 'z', строка 108
ошибка C2143: синтаксическая ошибка: отсутствует ';'перед строкой '}' ошибка 108
C2143: синтаксическая ошибка: отсутствует ';'до '}' строка 108
ошибка C2059: синтаксическая ошибка: '}' строка 108
ошибка C2065: 'xyz': необъявленная строка идентификатора 112

Не могу разобраться!Кажется, что проблема вызвана ## в:

#define OUTER(a, b) \
    a##b

, но почему (и как это исправить) мне не хватает ...

Ответы [ 3 ]

9 голосов
/ 01 августа 2010

Используйте это вместо:

#define CONCAT(X,Y) X##Y
#define OUTER(a, b) CONCAT(a,b)
#define INNER(a, b) CONCAT(a,b)

enum foo {
    OUTER(INNER(x, y),z)
}; // line 108

int main(...)
{
    foo bar = xyz; // line 112
}
2 голосов
/ 01 августа 2010

Предварительная обработка вашего примера с gcc приводит к:

enum foo {
t.c:7:1: error: pasting ")" and "z" does not give a valid preprocessing token
    xy z
};

, который должен дать вам понять, почему решение Лютера работает, а ваше - нет.

1 голос
/ 01 августа 2010

Если вы используете gcc, то вы можете задать ему опцию -E, чтобы увидеть предварительно обработанный вывод. Затем вы можете легко увидеть, что выводит препроцессор и как отлаживать ваши макросы. Другие компиляторы также имеют аналогичные параметры.

...