C++ 为自定义打印/日志功能的错误使用添加编译器警告

key*_*ard 4 c++ printing format compiler-warnings

我有以下功能,我想在使用 printf 时发出警告:

void LoggingManager::log(int32_t logLevel, const char *p_str, ...)
{
    va_list args;
    va_start(args, p_str);
    vsnprintf(s_LogginManagerBuffer, LOGGING_MANAGER_BUFFER_SIZE - 1, p_str, args);
    va_end(args);

    internalLog(s_LogginManagerBuffer);
}
Run Code Online (Sandbox Code Playgroud)

如果我忘记为格式字符串中的一个标记添加参数,我想以某种方式发出警告。警告太多(或错误的论点)也会很棒。由于忘记了日志记录功能中的参数,我最近遇到了一些崩溃。

如果不可能这样做,我怎么能重写我的函数,有警告但功能相同?

Kev*_*vin 5

如果您使用的是 gcc/g++/clang,则可以使用此页面上指定的格式属性:

格式(原型、字符串索引、第一个检查)

format 属性指定函数采用应针对格式字符串进行类型检查的 printf、scanf、strftime 或 strfmon 样式参数。例如,声明:

extern int my_printf (void *my_object, const char *my_format, ...) __attribute__ ((format (printf, 2, 3)));

使编译器检查对 my_printf 的调用中的参数是否与 printf 样式格式字符串参数 my_format 保持一致。

__attribute__是在函数原型之前还是之后并不重要。

因此,在您的情况下,您可以执行以下操作:

class LoggingManager {
    ...
public:
    void log(int32_t logLevel, const char *p_str, ...) __attribute__((format (printf, 3, 4)));
    ...
};
Run Code Online (Sandbox Code Playgroud)

请注意,因为这是一个成员函数,所以您需要考虑this传递的隐式参数。所以格式字符串实际上是第三个参数而不是第二个参数。(format (printf, 3, 4)而不是format (printf, 2, 3))

看到它在这里工作。