g++ 4.8.5:不使用 ## 提供有效的预处理标记
g++ 4.8.5 : does not give a valid preprocessing token using ##
当我尝试在 Linux 中使用 G++ 4.8 编译我的程序时出现错误 "does not give a valid preprocessing token"。当我在 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");
^
感谢您的帮助
在这种情况下,g++ 是正确的。 <<##varname1
的语义是 <<
和 varname1
的扩展值被粘贴到一个标记中,即 <<"area"
被编译器视为单个标记,因为这是不是有效令牌,它会报告错误。
您不需要每次在宏中使用参数时都使用 ##
。
只有当您想要将参数与其他一些文本连接起来以形成单个"token"时才需要这样做。例如,如果您有 "bo" 和 "ol" 并且想要制作 "bool".
在这种情况下,<<
和 "area"
应该是不同的标记。事实上,<<"area"
不是有效的标记。
由于你的论点本身就是一个标记,你只需将它写在代码中即可:
#define func(type1,varname1) \
cout << "ma var est " << varname1 << " et le type est " << #type1; \
cout << endl;
令牌几乎是单词,但它们是编程语言单词而不是英语单词。您可以在有关解析器的书籍或指南中阅读有关 tokens 的更多信息。
(您可能仍然需要 #type1
,因为它做了一些不同的事情:将参数转换为其值的字符串化版本。但是,由于您已经传递了一个字符串 "int"
,目前你也不需要它。)
It work perfectly in CCSunStudio
实际上这意味着它不能在 Sun Studio 中正常工作!
i do not have error when i compile it in Solaris with CCSunStudio.
这似乎是因为 Sun Studio 与古董 K&R C 具有一定程度的兼容性,which did things a bit differently。
您可以使用 the -xtransition
option 查找您的代码需要更新以符合标准的其他地方。
当我尝试在 Linux 中使用 G++ 4.8 编译我的程序时出现错误 "does not give a valid preprocessing token"。当我在 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");
^
感谢您的帮助
在这种情况下,g++ 是正确的。 <<##varname1
的语义是 <<
和 varname1
的扩展值被粘贴到一个标记中,即 <<"area"
被编译器视为单个标记,因为这是不是有效令牌,它会报告错误。
您不需要每次在宏中使用参数时都使用 ##
。
只有当您想要将参数与其他一些文本连接起来以形成单个"token"时才需要这样做。例如,如果您有 "bo" 和 "ol" 并且想要制作 "bool".
在这种情况下,<<
和 "area"
应该是不同的标记。事实上,<<"area"
不是有效的标记。
由于你的论点本身就是一个标记,你只需将它写在代码中即可:
#define func(type1,varname1) \
cout << "ma var est " << varname1 << " et le type est " << #type1; \
cout << endl;
令牌几乎是单词,但它们是编程语言单词而不是英语单词。您可以在有关解析器的书籍或指南中阅读有关 tokens 的更多信息。
(您可能仍然需要 #type1
,因为它做了一些不同的事情:将参数转换为其值的字符串化版本。但是,由于您已经传递了一个字符串 "int"
,目前你也不需要它。)
It work perfectly in CCSunStudio
实际上这意味着它不能在 Sun Studio 中正常工作!
i do not have error when i compile it in Solaris with CCSunStudio.
这似乎是因为 Sun Studio 与古董 K&R C 具有一定程度的兼容性,which did things a bit differently。
您可以使用 the -xtransition
option 查找您的代码需要更新以符合标准的其他地方。