日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

在C语言中以编程的方式获取函数名

發(fā)布時(shí)間:2025/3/15 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在C语言中以编程的方式获取函数名 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在C語(yǔ)言中以編程的方式獲取函數(shù)名

  僅僅為了獲取函數(shù)名,就在函數(shù)體中嵌入硬編碼的字符串,這種方法單調(diào)乏味還易導(dǎo)致錯(cuò)誤,不如看一下怎樣使用新的C99特性,在程序運(yùn)行時(shí)獲取函數(shù)名吧。
  
  對(duì)象反射庫(kù)、調(diào)試工具及代碼分析器,經(jīng)常會(huì)需要在運(yùn)行時(shí)訪問(wèn)函數(shù)的名稱,直到不久前,唯一能完成此項(xiàng)任務(wù)并且可移植的方法,是手工在函數(shù)體內(nèi)嵌入一個(gè)帶有該函數(shù)名的硬編碼字符串,不必說(shuō),這種方法非常單調(diào)無(wú)奇,并且輕易導(dǎo)致錯(cuò)誤。本文將要演示怎樣使用新的C99特性,在運(yùn)行時(shí)獲取函數(shù)名。
  
  那么怎樣以編程的方式從當(dāng)前運(yùn)行的函數(shù)中得到函數(shù)名呢?
  
  答案是:使用__FUNCTION__ 及相關(guān)宏。
  
   引出問(wèn)題
  
  通常,在調(diào)試中最讓人心煩的階段,是不斷地檢查是否已調(diào)用了特定的函數(shù)。對(duì)此問(wèn)題的解決方法,一般是添加一個(gè)cout或printf()——假如你使用C語(yǔ)言,如下所示:
  
  void myfunc()
  {
  cout<<"myfunc()"<<endl;
  //其他代碼
  }
  通常在一個(gè)典型的工程中,會(huì)包含有數(shù)千個(gè)函數(shù),要在每個(gè)函數(shù)中都加入一條這樣的輸出語(yǔ)句,無(wú)疑難過(guò)上“蜀山”啊,因此,需要有一種機(jī)制,可以自動(dòng)地完成這項(xiàng)操作。
  
   獲取函數(shù)名
  
  作為一個(gè)C++程序員,可能經(jīng)常碰到 __TIME__、__FILE__、__DATE__ 這樣的宏,它們會(huì)在編譯時(shí),分別轉(zhuǎn)換為包含編譯時(shí)間、處理的轉(zhuǎn)換單元名稱及當(dāng)前時(shí)間的字符串。
  
  在最新的ISO C標(biāo)準(zhǔn)中,如大家所知的C99,加入了另一個(gè)有用的、類似宏的表達(dá)式__func__,其會(huì)報(bào)告未修飾過(guò)的(也就是未裁剪過(guò)的)、正在被訪問(wèn)的函數(shù)名。請(qǐng)注重,__func__不是一個(gè)宏,因?yàn)轭A(yù)處理器對(duì)此函數(shù)一無(wú)所知;相反,它是作為一個(gè)隱式聲明的常量字符數(shù)組實(shí)現(xiàn)的:
  
  static const char __func__[] = "function-name";
  在function-name處,為實(shí)際的函數(shù)名。為激活此特性,某些編譯器需要使用特定的編譯標(biāo)志,請(qǐng)查看相應(yīng)的編譯器文檔,以獲取具體的資料。
  
  有了它,我們可免去大多數(shù)通過(guò)手工修改,來(lái)顯示函數(shù)名的苦差事,以上的例子可如下所示進(jìn)行重寫:
  
  void myfunc()
  {
  cout<<"__FUNCTION__"<<endl;
  }
  官方C99標(biāo)準(zhǔn)為此目的定義的__func__標(biāo)識(shí)符,確實(shí)值得大家關(guān)注,然而,ISO C++卻不完全支持所有的C99擴(kuò)展,因此,大多數(shù)的編譯器提供商都使用 __FUNCTION__ 取而代之,而 __FUNCTION__ 通常是一個(gè)定義為 __func__ 的宏,之所以使用這個(gè)名字,是因?yàn)樗咽艿搅舜蠖鄶?shù)的廣泛支持。
  
  在Visual Studio 2005中,默認(rèn)情況下,此特性是激活的,但不能與/EP和/P編譯選項(xiàng)同時(shí)使用。請(qǐng)注重在IDE環(huán)境中,不能識(shí)別__func__ ,而要用__FUNCTION__ 代替。
  
  Comeau的用戶也應(yīng)使用 __FUNCTION__ ,而不是 __func__ 。
  
  C++ BuilderX的用戶則應(yīng)使用稍稍不同的名字:__FUNC__ 。
  
  GCC 3.0及更高的版本同時(shí)支持 __func__ 和__FUNCTION__ 。
  
  一旦可自動(dòng)獲取當(dāng)前函數(shù)名,你可以定義一個(gè)如下所示顯示任何函數(shù)名的函數(shù):
  
  void show_name(const char * name)
  {
  cout<<name<<endl;
  }
  
  void myfunc()
  {
  show_name(__FUNCTION__); //輸出:myfunc
  }
  
  void foo()
  {
  show_name(__FUNCTION__); //輸出:foo
  }
  因?yàn)?__FUNCTION__ 會(huì)在函數(shù)大括號(hào)開始之后就立即初始化,所以,foo()及myfunc()函數(shù)可在參數(shù)列表中安全地使用它,而不用擔(dān)心重載。
  
   簽名與修飾名
  
  __FUNCTION__ 特性最初是為C語(yǔ)言設(shè)計(jì)的,然而,C++程序員也會(huì)經(jīng)常需要有關(guān)他們函數(shù)的額外信息,在Visual Studio 2005中,還支持另外兩種非標(biāo)準(zhǔn)的擴(kuò)展特性:__FUNCDNAME__ 與 __FUNCSIG__ ,其分別轉(zhuǎn)譯為一個(gè)函數(shù)的修飾名與簽名。函數(shù)的修飾名非常有用,例如,在你想要檢查兩個(gè)編譯器是否共享同樣的ABI時(shí),就可派得上用場(chǎng),另外,它還能幫助你破解那些含義模糊的鏈接錯(cuò)誤,甚至還可用它從一個(gè)DLL中調(diào)用另一個(gè)用C++鏈接的函數(shù)。在下例中,show_name()報(bào)告了函數(shù)的修飾名:
  
  void myfunc()
  {
  show_name(__FUNCDNAME__); //輸出:?myfunc@@YAXXZ
  }
  一個(gè)函數(shù)的簽名由函數(shù)名、參數(shù)列表、返回類型、內(nèi)含的命名空間組成。假如它是一個(gè)成員函數(shù),它的類名和const/volatile限定符也將是簽名的一部分。以下的代碼演示了一個(gè)獨(dú)立的函數(shù)與一個(gè)const成員函數(shù)簽名間的不同之處,兩個(gè)函數(shù)的名稱、返回類型、參數(shù)完全相同:
  
  void myfunc()
  {
  show_name(__FUNCSIG__); // void __cdecl myfunc(void)
  }
  
  strUCt S
  {
  void myfunc() const
  {
  show_name(__FUNCSIG__); //void __thiscall S::myfunc(void) const
  
   }
  };

總結(jié)

以上是生活随笔為你收集整理的在C语言中以编程的方式获取函数名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。