C++ 如何通过GCC检测vsnprintf中的隐式转换
我希望g++在vsnprintf中检测以下不正确的隐式转换。 我尝试:C++ 如何通过GCC检测vsnprintf中的隐式转换,c++,gcc,g++,printf,C++,Gcc,G++,Printf,我希望g++在vsnprintf中检测以下不正确的隐式转换。 我尝试: g++ -Wall -Werror -Wconversion -Wformat test.cpp -o test.ext 但没有任何警告。代码如下: #include <cstdio> #include <cstdarg> void PrintFError ( const char * format, ... ) { char buffer[256]; va_list args;
g++ -Wall -Werror -Wconversion -Wformat test.cpp -o test.ext
但没有任何警告。代码如下:
#include <cstdio>
#include <cstdarg>
void PrintFError ( const char * format, ... )
{
char buffer[256];
va_list args;
va_start (args, format);
vsnprintf (buffer,256,format, args);
perror (buffer);
va_end (args);
}
enum LEVEL
{
INFO = 1,
WRN = 2
};
int main ()
{
PrintFError ("Error opening %s", WRN); // WRN is enum not char*, expecte some compile warning here
return 0;
}
#包括
#包括
void PrintFError(常量字符*格式,…)
{
字符缓冲区[256];
va_列表参数;
va_开始(参数,格式);
vsnprintf(缓冲区,256,格式,参数);
缓冲区;
va_端(args);
}
枚举级别
{
INFO=1,
WRN=2
};
int main()
{
PrintFError(“打开%s时出错”,WRN);//WRN是枚举而不是字符*,此处需要一些编译警告
返回0;
}
当您将参数传递给…
,而不是在printf
内部时,这种类型的转换在调用站点发生
有关更多详细信息,请参阅
枚举数转换为
int
。但是,C++11作用域枚举数不会隐式转换。您必须向函数添加属性以允许gcc检查:
void PrintFError ( const char * format, ... ) __attribute__ ((format (printf, 1, 2)))
现在最好使用可变模板。差不多
template <typename ...Ts>
void PrintFError (const char * format, Ts&&...args)
{
char buffer[256];
vsnprintf (buffer, 256, format, std::forward<Ts>(args)...);
perror (buffer);
}
模板
void PrintFError(常量字符*格式,Ts&…args)
{
字符缓冲区[256];
vsnprintf(缓冲区,256,格式,标准::转发(args)…);
缓冲区;
}
如果您正在使用或,您可以利用它们的功能,将您的打印功能声明为
void PrintFError ( const char * format, ...)
__attribute__(format(printf(1,2)));
之后直接使用该函数可能会触发警告
顺便说一句,您还可以通过使用扩展来定制最近的g++
(或者gcc
,如果是用C编写的)编译器。然后,您可以定义自己的函数属性,并添加自己的检查优化过程。这将花费你至少一周的时间,除非你非常熟悉GCC的内部结构
<>最后,在C++(不在C)中,可以定义自己的输出<代码>运算符是的,C++ 11强枚举类型是枚举类型的一种解决方案。但替换遗留代码是一项巨大的工作。我希望在实用程序函数(日志打印)中找到一些常用方法
#define MY_ERROR_AT(Fil,Lin,Out) do { \
std::cerr << Fil << ":" << Lin << ": " << Out << std::endl; } \
while(0)
#define MY_ERROR(Out) MY_ERROR_AT(__FILE__,__LINE__,Out)