首页 > 解决方案 > 有没有办法在c ++中没有宏来获取行号?

问题描述

我正在编写一个记录器,我希望记录器还记录调用它的行、函数和文件。我已经尝试过#define my_logger(format, ...) _log(format, __LINE__, __PRETTY_FUNCTION__, __FILE__, __VA_ARGS__),但是,这给我带来了几个问题(我不能轻易地重载它,我不能把它放在一个命名空间中,而不是最便携的等等)。

有没有一种方法可以让我声明一个普通函数,void my_logger(const char* format, ...)并且在函数定义中让它知道调用它的行,__LINE_FUNCTION_WAS_CALLED_FROM__如果存在这样的宏?至少它需要在 GCC 上工作,并且真的应该是跨平台的。

编辑:跨平台,我只指 x86 和 ARM 上的 Linux 和 Windows

标签: c++gcc

解决方案


不能有这样的宏__LINE_FUNCTION_WAS_CALLED_FROM__。没有办法奏效。

从 C++20 开始,有一种方法可以通过传递默认的 initialized 将行、函数等转换为普通函数std::source_location

void log(std::string_view message,
         std::source_location location = std::source_location::current());

但是,由于它依赖于默认参数,因此可变参数实现起来有点棘手:How to use source_location in a variadic template function?

在 C++20 之前,宏是您唯一的可移植选项。


我看到你调用了一个_log在你的宏中命名的函数。该标识符保留给全局命名空间中的语言实现。您可能应该为该函数指定另一个名称以避免未定义的行为。

log也保留在全局命名空间中。无论如何,您都应该在自定义命名空间中声明所有名称(自然而然的自定义命名空间除外)。


[宏是] ...不是最便携的

如果您要替换__PRETTY_FUNCTION____func__,则该宏将可移植到所有符合标准的编译器 - 尽管由 给出的确切字符串__func__可能因实现而异。


推荐阅读