2009-10-12 28 views
2

我想寫一個C宏這需要這樣的:我可以用__func__替換C宏中的標識符名稱嗎?

int foo() { 
    MY_MACRO 
} 

,並擴展到這一點:

int foo() { 
    _macro_var_foo++; 
} 

我發現我不能使用__func__,因爲沒有按實際上並沒有在宏觀上擴大;它被預處理器像變量一樣處理。

有沒有辦法讓這個工作?

回答

3

預處理器不知道函數,只是源文件和行號。在那個階段,它不執行語法分析,只是文本分析和替換。這就是爲什麼__func__是一個神奇的變量,而不是像神奇的宏像__FILE____LINE__

+0

這非常明智。但我的理解是GCC已經習慣了我想要的。我很失望,沒有辦法得到這個功能了。 – 2009-10-12 02:59:34

1

您可以使用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 
+0

不幸的是,你不能在宏中連接'__func__',因爲預處理器把它當作一個變量來對待。 – 2009-10-12 03:20:07

+0

我建議你取消__func__的使用,而是將你的函數名稱傳遞給FUNC_WRAPPER()。同樣的結果。 – DMC 2009-10-12 03:22:56

+0

您是否計劃展示如何處理參數列表? – 2009-10-12 03:30:28

1

技術上,回答你的問題是「是」,有「某種方式」。但是我認爲你已經知道這一點,並且在宏預處理器級別無法處理這一點是事實。

當然,總有一種方法,你可能需要在圖靈機上有一個非常長的磁帶。

我想你已經知道這一點,但備案你可以得到你想要的總的結果:所以現在

#define MY_MACRO f_dictionary(__func__, ADDONE); 

,你只需要實現f_dictionaryADDONE OP它。

+0

哈哈,是的。但是在那個時候,我不妨在宏中輸入函數的名字。 :) – 2009-10-12 03:20:54

3

在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__一直是變量。

如果有一種方法可以乾淨地將函數名轉換爲預處理器,那麼這裏的文檔很可能會交叉引用它,如果沒有定義的話。

相關問題