![](/img/trans.png)
[英]Preprocessor pasting of UTF-8 characters does 'not give a valid preprocessing token' in g++
[英]g++ 4.8.5 : does not give a valid preprocessing token using ##
當我嘗試在 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");
^
謝謝你的幫助
您不需要每次在宏中使用參數時都使用##
。
僅當您想將參數與其他文本連接時才需要它,以形成單個“標記”。 例如,如果你有 "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
選項來查找代碼需要更新以符合標准的其他地方。
在這種情況下 g++ 是正確的。 <<##varname1
的語義是<<
和varname1
的擴展值被粘貼到一個標記中,即<<"area"
被編譯器視為單個標記,並且由於這不是一個有效標記,因此它報告一個錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.