我想寫一個C宏這需要這樣的:我可以用__func__替換C宏中的標識符名稱嗎?
int foo() {
MY_MACRO
}
,並擴展到這一點:
int foo() {
_macro_var_foo++;
}
我發現我不能使用__func__
,因爲沒有按實際上並沒有在宏觀上擴大;它被預處理器像變量一樣處理。
有沒有辦法讓這個工作?
我想寫一個C宏這需要這樣的:我可以用__func__替換C宏中的標識符名稱嗎?
int foo() {
MY_MACRO
}
,並擴展到這一點:
int foo() {
_macro_var_foo++;
}
我發現我不能使用__func__
,因爲沒有按實際上並沒有在宏觀上擴大;它被預處理器像變量一樣處理。
有沒有辦法讓這個工作?
預處理器不知道函數,只是源文件和行號。在那個階段,它不執行語法分析,只是文本分析和替換。這就是爲什麼__func__
是一個神奇的變量,而不是像神奇的宏像__FILE__
和__LINE__
。
您可以使用token concatenation來做到這一點。
#define MY_MACRO(baz) _macro_var_##baz++;
#define FUNC_WRAPPER(bar)\
int bar()\
{\
MY_MACRO(bar)\
}
FUNC_WRAPPER(foo)
從GCC -E輸出:
int foo(){ _macro_var_foo++;}
版本使用複雜的宏和X宏與參數列表處理:
#define MY_MACRO(baz) _macro_var_##baz++;
#define FUNC_DEF(ret_type,bar,...)\
ret_type bar(__VA_ARGS__)\
{\
MY_MACRO(bar)\
FUNC_CONTENTS\
}
#define FUNC_CONTENTS\
printf("Do some stuff\n", s1, s2);
FUNC_DEF(int, foo, char *s1, char *s2)
#undef FUNC_CONTENT
不幸的是,你不能在宏中連接'__func__',因爲預處理器把它當作一個變量來對待。 – 2009-10-12 03:20:07
我建議你取消__func__的使用,而是將你的函數名稱傳遞給FUNC_WRAPPER()。同樣的結果。 – DMC 2009-10-12 03:22:56
您是否計劃展示如何處理參數列表? – 2009-10-12 03:30:28
技術上,回答你的問題是「是」,有「某種方式」。但是我認爲你已經知道這一點,並且在宏預處理器級別無法處理這一點是事實。
當然,總有一種方法,你可能需要在圖靈機上有一個非常長的磁帶。
我想你已經知道這一點,但備案你可以得到你想要的總的結果:所以現在
#define MY_MACRO f_dictionary(__func__, ADDONE);
,你只需要實現f_dictionary
和ADDONE
OP它。
哈哈,是的。但是在那個時候,我不妨在宏中輸入函數的名字。 :) – 2009-10-12 03:20:54
在C99標準,__func__
給出「預定義的識別符」的一個特殊的新的類別(在第6.4.2.2預定義的標識符):
標識符
__func__
應由翻譯被隱式地聲明爲如果 緊隨每個函數定義的左括號,聲明static const char __func__[] = "function-name";
出現,其中函數名是詞法收納功能的名稱
這意味着它超出了C預處理器的範圍,它不知道函數邊界或函數名。此外,它會擴展爲一個字符串,這使得它不適合嵌入到變量名稱中。
的GCC(4.4.1)手冊中部分5.43(函數名作爲String)表示:
這些標識符[意
__func__
,__FUNCTION__
和__PRETTY_FUNCTION__
]不預處理宏。在GCC 3.3及更早版本中,僅在C中,__FUNCTION__
和__PRETTY_FUNCTION__
被視爲字符串文字;他們可以用 初始化字符數組,並且可以將它們與其他字符串字面值連接起來。 GCC 3.4和更高版本將它們視爲變量,如__func__
。在C++中,__FUNCTION__
和__PRETTY_FUNCTION__
一直是變量。
如果有一種方法可以乾淨地將函數名轉換爲預處理器,那麼這裏的文檔很可能會交叉引用它,如果沒有定義的話。
這非常明智。但我的理解是GCC已經習慣了我想要的。我很失望,沒有辦法得到這個功能了。 – 2009-10-12 02:59:34