Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;添加错误使用自定义打印/日志函数的编译器警告_C++_Printing_Format_Compiler Warnings - Fatal编程技术网

C++ C++;添加错误使用自定义打印/日志函数的编译器警告

C++ C++;添加错误使用自定义打印/日志函数的编译器警告,c++,printing,format,compiler-warnings,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); inte

我有以下功能,我希望在使用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属性指定函数接受printf、scanf、strftime或strfmon样式的参数,这些参数应根据格式字符串进行类型检查。例如,宣言:

extern int my_printf(void*my_对象,const char*my_格式,…)
__属性(格式(printf,2,3))

使编译器检查调用my_printf时的参数与printf样式格式字符串参数my_format的一致性

\uu属性是在函数原型之前还是之后并不重要

因此,在您的情况下,您可以这样做:

class LoggingManager {
    ...
public:
    void log(int32_t logLevel, const char *p_str, ...) __attribute__((format (printf, 3, 4)));
    ...
};
请注意,因为这是一个成员函数,所以您需要考虑传递的隐式
this
参数。所以格式字符串实际上是第三个参数,而不是第二个。(
格式(printf,3,4)
而不是
格式(printf,2,3)


查看它的工作情况。

如果您使用的是Visual Studio,则可以使用
\u Printf\u format\u string\u
宏:

#include <sal.h>

void log
(
    int32_t                                    log_level
,   _In_z_ _Printf_format_string_ const char * psz_format
,   ...
);
#包括
空位日志
(
int32\u t日志级别
,_In_z__打印格式_字符串uu常量字符*psz_格式
,   ...
);
要使代码可移植,可能需要在必要时定义格式属性宏和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);
#如果已定义(uu GNUC_uu)
#定义属性(格式索引,变量索引)属性(格式索引,变量索引)
#否则
#定义属性(格式索引、变量索引)
#恩迪夫
#如果已定义(\u MSC\u VER)
#包括
#否则
#在z中定义_
#定义打印格式字符串_
#恩迪夫
空位日志
(
int32\u t日志级别
,_In_z__打印格式_字符串uu常量字符*psz_格式
,   ...
)属性_PRINTF(2,3);

请注意。@DanielH谢谢!更新我的答案。谢谢!这是非常漂亮的,并且为我展示了如何在我的成员函数中使用它而获得了额外的积分!:)请不要用c标记,这不是有效的c代码。对我不起作用。如果我用Printf_format_string声明我自己的函数,我不会得到任何警告,如果我使用标准的sprintf,一切都正常。VS2017 15.9.7,包括在内。有什么想法吗?@ GeoGeHAZAN可能警告被禁止或C++代码分析不执行。当我用PrtTF替换自己的函数而不改变任何其他东西时,警告就存在,所以这不是问题,我在短片段中总结了这个问题: