我正在将MFC应用程序从VS2003迁移到VS2010。数以千计的函数调用如_tcsset,_tcscpy,_tcsupr等。在迁移后构建时,C4996警告建议使用这些函数的_s版本。我被要求不使用_CRT_SECURE_NO_WARNINGS并通过更改这些调用删除所有警告并使用_s版本。有数千个调用,在许多情况下,TCHAR *来自外部作为参数。我不知道目标缓冲区有多大。那么,我最好的选择是什么? e.g。
TCHAR* fnc(TCHAR* tsrc, TCHAR* tdest)
{
_tcsset(tsrc,0);
_tcscpy(tdest,tsrc);
return(tdest);
}
如果我需要将这些调用更改为_tcscpy_s。我该怎么办?在这种情况下使用非_s版本不是更好吗?
答案 0 :(得分:0)
如果您被告知要更改使用_s
的所有功能,则必须继续操作并执行此操作。您的示例函数必须更改为:
TCHAR* fnc(TCHAR* tsrc, size_t src_els, TCHAR* tdest, size_t dst_els)
{
_tcsset_s(tsrc, src_els, 0);
_tcscpy(tdest, dst_els, tsrc);
return(tdest);
}
...然后你必须改变对它的调用以匹配,并且可能必须将长度传递给那些函数,泡沫,冲洗,重复。
另一种方法是切换到std::tstring
(其中tstring
是string
或wstring
的typedef(视情况而定)。这将是同样多的工作,但会导致更清晰的界面很多更难以导致缓冲区溢出。
作为一个侧面问题,您是否仍然在宽版和窄版中构建代码?如果没有,我会借此机会完全撕掉TCHAR,并使用wchar_t
。
如果您不使用std::string/wstring
,则应该使用SAL注释,因此该函数将声明为:
TCHAR* fnc(
__inout_ecount(src_els) TCHAR* tsrc, size_t src_els,
__out_ecount(dst_els) TCHAR* tdest, size_t dst_els)
这样,工具集可以(至少在某种程度上)检查您是否传递了正确的值。
您可能还想编写为您计算元素的函数的模板化版本:
template <size_t s, size_t d>
TCHAR *fnc( TCHAR (&tsrc)[s], TCHAR (&tdest)[d] )
{
return fnc( tsrc, s, tdest, d );
}