簡體   English   中英

如何使用 __LINE__ 或其他方法從呼叫站點獲取行號?

[英]How to get the line number from the call site using __LINE__ or some other method?

考慮一下我寫的這個簡短的程序:

    #include <iostream>
    
    template<bool Debug = false>
    constexpr int add(const int& a, const int& b) { 
        if (Debug)
            std::cout << __FUNCTION__ << " called on line " << __LINE__ << '\n';
        return (a + b);
    }
    
    int main() {
        std::cout << add(3, 7) << '\n';
        std::cout << add<true>(5, 9) << '\n';
        return 0;
    }

它工作得很好,它給出了正確的 output:

10
add called on line 6
14

但是,我希望打印的行號是程序調用站點的行,在這個程序中應該是第 12 行。

那么如何使用__LINE__或其他方法來給我調用 function 的行號?

所需的 output 將是:

10
add called on line 12
14

如果可能的話,我希望它由 function 本身生成。


-編輯-

作為給讀者的說明,我對任何和所有選項持開放態度,但對於我當前的構建環境,我僅限於 C++17 並且我正在使用 Visual Studio。

你可以這樣稱呼它:

template<bool Debug = false>
constexpr int add(const int& a, const int& b, int loc = __LINE__) { 
    if (Debug)
        std::cout << __FUNCTION__ << " called on line " << loc << '\n';
    return (a + b);
}

int main() {
    std::cout << add(3, 7) << '\n';
    std::cout << add<true>(5, 9, __LINE__) << '\n';
    return 0;
}

Output:

10
add called on line 14
14

此外,您可以定義一個宏來跳過第三個參數:

#define add_Debug(a, b) add<true>(a,b,__LINE__)

C++ 20 及以上

使用 C++20,我們得到std::source_location ,其中包含有關行號、function 和文件名的信息。 如果你的編譯器支持它,你可以使用它。 示例(使用 g++ 9.3.0 測試)。 您將不再需要宏:

#include <iostream>
#include <experimental/source_location>

using source_location = std::experimental::source_location;

template<bool Debug = false>
constexpr int add(const int& a, const int& b, source_location l = source_location::current()) { 
    if (Debug)
          // this will print 'main' as function name
          //std::cout << l.function_name() << " called on line " << l.line() << //'\n';
        std::cout << source_location::current().function_name() << " called on line " << l.line() << '\n';


    return (a + b);
}

int main()
{
    std::cout << add(3, 7) << '\n';
    std::cout << add<true>(5, 9) << '\n';

    return 0;
}

Output:

10
add<true> called on line 16
14

使用source_location您不必再使用宏。 它將正確打印該行

If you could compile your code on Linux using some recent GCC (in July 2020, that means GCC 10 ), you might compile with g++ -g -O -Wall then use Ian Taylor's libbacktrace (like we do in RefPerSys ) since that library parses DWARF調試信息。

您可以將該庫移植到您的操作系統並調試信息格式,或者找到一些等效的。

今天,一種更粗略的可能性可能是用宏包裝一些函數。 例如,不要用一些void foo(void);調用foo() ); 你將會擁有

extern void foo_at(const char*fileno, int lineno);
#define foo() foo_at(__FILE__,__LINE__);

事實上,C++20 應該添加功能測試source_location但您可能需要等待幾個月才能獲得支持它的編譯器。 考慮從其源代碼編譯最近的 GCC。 AFAIK MinGW 64在 Windows 上運行(所以請允許使用它)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM