【问题标题】:C++ Add compiler warnings for wrong usage of custom print/log functionC++ 为错误使用自定义打印/日志功能添加编译器警告
【发布时间】:2018-01-20 09:12:26
【问题描述】:

我有以下功能,我希望在使用 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);
}

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

如果无法做到这一点,我该如何重写我的函数,以获得警告但功能相同?

【问题讨论】:

  • 请不要用c标记,这不是有效的c代码。

标签: c++ printing format compiler-warnings


【解决方案1】:

如果您使用 gcc/g++/clang,您可以使用 this page 中指定的 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)

看到它工作here

【讨论】:

  • @DanielH 谢谢!更新了我的答案。
  • 谢谢!这是向我展示如何在我的会员功能中使用它的非常漂亮和奖励积分! :)
【解决方案2】:

如果您使用的是 Visual Studio,则可以使用 SAL annotation _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);

【讨论】:

  • 对我不起作用。如果我用 Printf_format_string 声明我自己的函数,我根本不会收到任何警告,如果我使用标准 sprintf,一切正常。 VS2017 15.9.7,包括 。有什么想法吗?
  • @GeorgeHazan 可能警告被禁止或 C++ 代码分析未执行。
  • 当我用 printf 替换我自己的函数而不更改任何其他内容时,会出现警告,所以这不是问题,我在简短的 sn-p 中总结了问题:stackoverflow.com/questions/54826028/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
相关资源
最近更新 更多