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



>我有以下函数,我想像使用 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);
}

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

如果无法做到这一点,我怎么能重写我的函数,让警告但功能相同?

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

格式(原型、字符串索引、先检查(

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)));
...
};

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

在这里看到它的工作。

如果您使用的是Visual Studio,则可以使用SAL注释_Printf_format_string_宏:

#include <sal.h>
void log
(
int32_t                                    log_level
,   _In_z_ _Printf_format_string_ const char * psz_format
,   ...
);

若要使代码可移植,可能需要在必要时定义格式属性宏和 SAL 宏替换:

#if defined(__GNUC__)
#define ATTRIBUTE_PRINTF(format_index, vargs_index) __attribute__((__format__ (__printf__, format_index, vargs_index)))
#else
#define ATTRIBUTE_PRINTF(format_index, vargs_index)
#endif
#if defined(_MSC_VER)
#include <sal.h>
#else
#define _In_z_
#define _Printf_format_string_
#endif
void log
(
int32_t                                    log_level
,   _In_z_ _Printf_format_string_ const char * psz_format
,   ...
) ATTRIBUTE_PRINTF(2, 3);

相关内容

  • 没有找到相关文章

最新更新