g ++ 4.8.5:未使用##给出有效的预处理令牌

Abd*_*ami 0 c++ preprocessor g++ c-preprocessor

当我尝试在Linux中使用G ++ 4.8编译程序时出现错误“未提供有效的预处理令牌”。并且在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");
}

Run Code Online (Sandbox Code Playgroud)

它可以在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");
 ^
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助

Lig*_*ica 5

您不需要##每次在宏中使用参数时都使用。

仅在要将自变量与其他文本连接起来以形成单个“令牌” 时才需要。例如,如果您有“ bo”和“ ol”并想制作“ bool”。

在这种情况下,<<并且"area"应该是不同的标记。实际上,<<"area"这不是有效的令牌。

由于您的参数本身就是一个标记,因此您只需将其写在代码中即可:

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

令牌几乎是单词,但是它们是编程语言单词,而不是英语单词。您可以在一本书中阅读有关令牌的更多信息,也可以在解析器指南中阅读更多信息。

(您可能仍然需要#type1,因为这会做一些不同的事情:将参数转换为其值的字符串化版本。但是,由于您已经传递了字符串"int",因此当前也不需要它。)


它在CCSunStudio中完美运行

实际上,这意味着它在Sun Studio 中无法正常工作!

在带有CCSunStudio的Solaris中进行编译时,我没有错误。

这似乎是因为Sun Studio与古董K&R C具有一定程度的兼容性,这在功能上有所不同

您可以使用-xtransition选项查找代码需要更新以符合标准的其他位置。