2016-01-11 30 views
0

我想通過宏或一些編譯器魔法獲得代碼中的完整函數路徑和聲明。我有這樣的代碼(click here to run):C++宏得到完整的函數路徑和聲明

#include <iostream> 

namespace NS { 

    struct Foo { 
     static int sum(int a, int b) { 
      std::cout << "This is from " << __FILE__ << ":" << __LINE__ << " @ " <<  __func__ << std::endl; 
      return a+b; 
     } 

     static int sum(int a, int b, int c) { 
      std::cout << "This is from " << __FILE__ << ":" << __LINE__ << " @ " <<  __func__ << std::endl; 
      return a+b+c; 
     } 

    }; 
} 

int main() { 
    NS::Foo::sum(1,2); 
    NS::Foo::sum(1,2, 3); 
} 

而我得到的輸出:

This is from /some/where/main.cpp:7 @ sum 
This is from /some/where/main.cpp:12 @ sum 

我的問題是:

  • 我如何獲得sum功能的完整路徑調用? ?(NS::Foo::sum)
  • 我怎樣才能得到完整的函數聲明與參數類型(sum(int, int)sum(int, int, int)

我感興趣的主流編譯器:Clang, GCC, Microsoft C++ compiler

+2

C不是C++不是C! – Olaf

+0

@Olaf,感謝您的編輯。我明白,這只是一個壞習慣。 –

+0

**前置處理器處理宏是有原因的。它們是文本替換,並且不瞭解「正常」C++代碼(btw。** this *與所有預處理器相同)。 – Olaf

回答

3

回答了GCC。

簽出__PRETTY_FUNCTION__宏。我在<assert.h>的宏定義中找到了assert。對於其他編譯器和libc實現也許可以找到同樣的結果。

+0

太棒了!它甚至在Clang中得到支持。謝謝 –

3

對於Microsoft Visual Studio編譯器,__FUNCSIG__可以給你很多關於該功能。

__FUNCSIG__會給你全功能簽名
__FUNCDNAME__給出了精美的名字。
__FUNCTION__僅用於函數名稱。

+0

似乎是我所需要的視覺工作室。謝謝 –

2

如果您不想將自己侷限於單個編譯器,也不喜歡編寫自己的預處理器ifdef鏈,boost已經定義了一個宏BOOST_CURRENT_FUNCTION,它被定義爲已定義的全功能簽名宏在使用的編譯器上。 __PRETTY_FUNCTION__在gcc和其他支持的編譯器中,__FUNCSIG__支持(msvc),還支持一些較少使用的編譯器,並回退到由C標準定義的__func__(或者即使不支持也是靜態佔位符)。