【问题标题】:g++ 4.8.5 : does not give a valid preprocessing token using ##g++ 4.8.5:不使用##提供有效的预处理令牌
【发布时间】:2020-02-26 17:50:14
【问题描述】:

当我尝试在 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");
}

它在 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");
 ^

感谢您的帮助

【问题讨论】:

  • 错误消息非常明确,并描述了错误是什么。那么你的问题是什么?
  • &lt;&lt;"area" 不是有效的预处理器令牌,因此您不能将它们 ## 放在一起。我猜你可能打错字了,意思是 # 单个哈希。

标签: c++ g++ c-preprocessor preprocessor


【解决方案1】:

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

仅当您想将参数与其他文本连接以形成单个“标记”时,您才需要这样做。例如,如果你有 "bo" 和 "ol" 并且想要制作 "bool"。

在这种情况下,&lt;&lt;"area" 应该是不同的标记。事实上,&lt;&lt;"area" 不是一个有效的令牌。

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

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

标记几乎是单词,但它们是编程语言单词而不是英语单词。您可以在有关解析器的书籍或指南中阅读更多关于 tokens 的信息。

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


在 CCSunStudio 中完美运行

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

我在 Solaris 中使用 CCSunStudio 编译时没有错误。

这似乎是因为 Sun Studio 与古董 K&R C which did things a bit differently 具有一定程度的兼容性。

您可以使用the -xtransition option 查找您的代码需要更新以符合标准的其他地方。

【讨论】:

  • 非常感谢您的回答,我有一个问题,是否可以使用 g++ 编译器跳过此错误?因为上面的代码只是一个例子,我公司的一个项目的很多c++类都有错误,我宁愿跳过这个错误而不是修改代码。
  • @AbdelhakimAitErrami 你不能让 GCC 接受这个错误的代码;它根本不理解代码。您将不得不修复代码。
  • 看起来您可以在 Sun Studio 编译器中使用 -xtransition 选项来识别您使用古董 K&R C 而不是 ISO C 的其他地方(Sun Studio 显然仍然接受某些组合两个都)。然后,您可以修复所有这些问题,从而生成标准的、可移植的代码库。 (ref)
【解决方案2】:

在这种情况下,g++ 是正确的。 &lt;&lt;##varname1 的语义是将&lt;&lt;varname1 的扩展值粘贴到一个标记中,即&lt;&lt;"area" 被编译器视为单个标记,由于这不是一个有效标记,因此会报告错误.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2022-01-09
    • 1970-01-01
    • 2015-02-06
    • 2011-06-07
    相关资源
    最近更新 更多