繁体   English   中英

如何在 cpp 中定义一个宏来打印文件 function 行?

[英]How do I define a macro to print file, function, line in cpp?

我正在尝试打印 function,它在打印语句前面加上文件、function 和行号。

function debug("test %d", 1)应该打印:

[src/main.cpp:main():8] test 1

这个答案声称可以做我想做的事,并且几乎可以做到,但不能按原样工作。 (而且这个问题与这个问题不一样)使用那个答案,我能够想出这个宏:

#include <cstdio>  //needed for printf
#define debug(a, args...) printf("[%s:%s():%d] " #a "\n", __FILE__, __func__ , __LINE__, ##args)

这与我想要的非常接近,但在字符串周围添加了引号,如下所示。 没有引号如何打印?

[src/main.cpp:main():8] "test 1"

您的宏定义有两个问题:

  1. 它使用了不正确的语法
  2. 变量的名称可以a ; 在这种情况下,您不能简单地将变量放在 2 个字符串文字旁边进行连接。

后一个问题可以通过使用字符串和+运算符或简单地使用多个printf来解决。

如果 C++20 __VA_OPT__可用,则可以使用以下解决方案。

#include <cstdio>
#include <utility>

namespace Logging
{
    template<typename ...Args>
    inline void Debug(size_t lineNumber, char const* filename, char const* functionName, char const* format, Args&&... args)
    {
        std::printf("[%s:%s():%zu] ", filename, functionName, lineNumber);
        std::printf(format, std::forward<Args>(args)...);
        std::printf("\n");
    }
}

#define debug(format, ...) ::Logging::Debug(__LINE__, __FILE__, __func__, format __VA_OPT__(,) __VA_ARGS__)

Pre C++ 20 你可以创建一个帮助程序 object 来处理仅使用单个参数的宏的情况

#include <cstdio>
#include <utility>

namespace Logging
{
    class Logger
    {
    public:
        Logger(size_t lineNumber, char const* filename, char const* functionName, char const* format)
            : m_lineNumber(lineNumber), m_filename(filename), m_functionName(functionName), m_format(format)
        {}

        template<class ...Args>
        inline void Debug(Args&&... args)
        {
            std::printf("[%s:%s():%zu] ", m_filename, m_functionName, m_lineNumber);
            std::printf(m_format, std::forward<Args>(args)...);
            std::printf("\n");
        }
    private:
        size_t m_lineNumber;
        char const* m_filename;
        char const* m_functionName;
        char const* m_format;
    };
}

#define debug(format, ...) ::Logging::Logger(__LINE__, __FILE__, __func__, format).Debug(__VA_ARGS__)

仅将#a替换为a

#define debug(a, args...) printf("[%s:%s():%d] " a "\n", __FILE__, __func__, __LINE__, ##args)

单个#后跟宏参数将参数字符串化 IOW,它接受调用者传递给参数的任何内容,并从中生成字符串文字。 例如:

#define macro(a) #a

macro(1)将是"1"macro(x+y)将是"x+y" ,等等。

如果参数包含引号字符,它们将作为实际字符存储在字符串文字中,这不是您在这种情况下想要的。 您的参数正在传递一个您想按原样使用的字符串文字,因此简单的宏替换就足够了,因此您需要删除# 您希望编译器看到"[%s:%s():%d] " "test %d" "\n"并因此将它们合并到"[%s:%s():%d] test %d\n" ,看不到"[%s:%s():%d] " "\"test %d\"" "\n"并将它们合并到"[%s:%s():%d] \"test %d\"\n" ,这是您在原始代码中看到的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM