我已经在Visual Studio上运行了代码分析器,在大型代码库上运行了大约10亿这个错误:
warning C6284: Object passed as parameter '3' when string is required in call to 'fprintf'
根据http://msdn.microsoft.com/en-us/library/ta308ywy.aspx“此缺陷可能会导致输出错误或崩溃。”然而,我的同事说我们可以毫无问题地忽略所有这些错误。所以我的一个问题是我们是否需要对此做任何事情,或者我们可以保留原样吗?
如果需要解决这些错误,最好的解决方法是什么?
这样做是否可行:
static_cast<const char*>(someCString)
对此有更好或更正确的方法吗?
以下行生成此警告:
CString str;
fprintf(pFile, "text %s", str);
答案 0 :(得分:2)
我假设您将Microsoft“CString”对象传递给printf() - 族函数,其中相应的格式说明符为%s
。如果我是对的,那么你的答案就在这里:How can CString be passed to format string %s?(简而言之,你的代码没问题。)
似乎最初的实现细节允许CString直接传递给printf(),后来它成为合同的一部分。所以你很高兴你的程序正确,但如果你想避免静态分析警告,你可能确实需要使用static_cast到char指针。我不确定它在这里是否值得...也许还有其他方法可以让这些工具放在一起,因为它们都来自微软。
答案 1 :(得分:2)
根据C6284中的MSDN建议,您可以抛弃警告。使用C ++强制转换是最易于维护的选项。您上面的示例将更改为
fprintf(pFile, "text %s", static_cast<const TCHAR*>(str));
或者,只是另一种拼写,
fprintf(pFile, "text %s", static_cast<LPCTSTR>(str));
最有说服力的选项( 100%无广告,请参阅编辑部分)
fprintf(pFile, "text %s", str.GetString());
当然,遵循任何这些更改模式将是第一个移植步骤,如果没有任何表明需要它,这可能是有害的(不仅仅是你的团队氛围。)
编辑:(根据xMRi的评论)
1)我添加了const
,因为该参数对于fprintf
2)对免铸解决方案CSimpleStringT::GetString的说明:CSimpleStringT
类模板用于CStringT
的定义,该模板再次用于键入定义类CString
用于原始问题
3)重新设计了消除噪音的答案。
4)减少关于铸造选项的介绍
答案 2 :(得分:0)
从技术上讲,它是可以的,因为c-string以这种方式存储在CString中,您可以按照说明使用它,但是依赖CString如何实现快捷方式并不好。 printf是一个C-runtime函数,对C ++对象一无所知,但这里依赖的是字符串首先存储在CString中 - 一个实现细节。
如果我没记错,最初CString无法以这种方式使用,并且必须将CString转换为c-string以将其打印出来,但在以后的版本中,MS更改了实现以允许将其视为c-字符串。
另一个突破性问题是UNICODE,如果你有一天决定使用UNICODE字符集编译程序肯定不会起作用,因为即使你将所有字符串格式化程序更改为%ld,嵌入式0也有时会阻止字符串被打印。
实际问题是为什么使用printf而不是C ++来打印/写入文件?