g ++ 4.8.5: не дает действительный токен предварительной обработки с использованием ## - PullRequest
1 голос
/ 31 октября 2019

У меня ошибка "не дает действительный токен предварительной обработки", когда я пытаюсь скомпилировать свою программу с G ++ 4.8 в Linux. и у меня нет ошибки при компиляции в Solaris с CCSuntudio.

ниже моего кода:

#include <iostream>

#define func(type1,varname1) \
        cout << "ma var est "<<##varname1<<" et le type est "<<#type1; \
        cout <<endl;

using namespace std;

int main() {
  func("int", "area");
}

Он отлично работает в CCSunStudio, но не с G ++

hello.hxx:2:23: error: pasting "<<" and ""area"" does not give a valid preprocessing token
  cout << "ma var est "<<##varname1<<" et le type est "<<#type1; \
                       ^
hello.cxx:7:1: note: in expansion of macro ‘func’
 func("int","area");
 ^

Спасибо за любую помощь

Ответы [ 2 ]

5 голосов
/ 31 октября 2019

Вам не нужно использовать ## каждый раз, когда вы используете аргумент в макросе.

Это нужно только тогда, когда вы хотите объединить аргумент с другим текстом,сформировать единый «токен». Например, если у вас есть «bo» и «ol» и вы хотите сделать «bool».

В этом случае << и "area" должны быть разными токенами. Фактически, <<"area" не будет действительным токеном.

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

#define func(type1,varname1) \
    cout << "ma var est " << varname1 << " et le type est " << #type1; \
    cout << endl;

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

(Вам все еще может понадобиться #type1, потому что это делает что-то другое: преобразование аргумента в строковую версию его значения. Однако, поскольку вы уже передаете строку "int", в настоящее времявам это там тоже не нужно.)


В CCSunStudio оно отлично работает

На самом деле это означает, что не правильно работает в Sun Studio!

У меня нет ошибки при компиляции в Solaris с помощью CCSunStudio.

Похоже, что в Sun Studio есть уровеньсовместимости со старинными K & R C, , которые сделали вещи немного по-другому .

Вы можете использовать параметр -xtransition , чтобы найти другие места, где ваш код требует обновления добыть стандартным.

1 голос
/ 31 октября 2019

В этом случае g ++ прав. Семантика <<##varname1 заключается в том, что << и расширенное значение varname1 вставляются в один токен, т. Е. <<"area" обрабатывается компилятором как один токен, и, поскольку это недопустимый токен, он сообщает об ошибке.

...