使用VS2005以上版本(VS2005、VS2008、VS2010)編譯在其他編譯器下正常通過的C語言程序,你可能會遇到類似如下的警告提示:
引用內容
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:/program files/microsoft visual studio 10.0/vc/include/string.h(105) : 參見“strcpy”的聲明
warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:/program files/microsoft visual studio 10.0/vc/include/stdio.h(234) : 參見“fopen”的聲明
原因解釋
這種微軟的警告,主要因為那些C庫的函數,很多函數內部是不進行參數檢測的(包括越界類的),微軟擔心使用這些會造成內存異常,所以就改寫了同樣功能的函數,改寫了的函數進行了參數的檢測,使用這些新的函數會更安全和便捷。關於這些改寫的函數你不用專門去記憶,因為編譯器對於每個函數在給出警告時,都會告訴你相應的安全函數,查看警告信息就可以獲知,在使用時也再查看一下MSDN詳細了解。
庫函數改寫例子:
mkdir改寫為 _mkdir
fopen”改寫為 fopen_s
stricmp改寫為 stricmp_s
strcpy改寫為strcpy_s
解決方案:
1> 根據下面的warning提示:參見“fopen”的聲明
消息:“This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.”
所以可以將函數按warning提示的第二句,改為使用fopen_s函數即可:
例如:FILE *pFile=fopen("1.txt", "w");
改為:
FILE* pFile;
fopen_s(&pFile, "1.txt", "w");
2> 還是根據warning提示的地三句話:use _CRT_SECURE_NO_DEPRECATE
項目|屬性|配置屬性|C/C++|命令行|附加選項,加入【/D "_CRT_SECURE_NO_DEPRECATE" 】(注:加入中括號中完整的內容)
3> 降低警告級別:項目|屬性|配置屬性|C/C++|常規,自己根據情況降低警告級別(此法不推薦)
注意:高度重視警告:使用編譯器的最高警告級別。應該要求構建是干凈利落的(沒有警告)。理解所有警告。通過 修改代碼而不是降低警告級別來排除警告。
編譯器是你的朋友。如果它對某個構造發出警告,這經常是說明你的代碼中存在潛在的問題。成功的構建應該是無聲無息的(沒有警告的)。
C++標准庫函數提供了字符和字符串的操作函數,並提供了其UNICODE版本,如:
char *strcpy(char *strDestination, const char *strSource);
wchar_t *wcscpy(wchar_t *strDestination, const wchar_t *strSource);
wcscpy()即為strcpy()的寬字符版本,與_T類似的,Visual C++提供了類似的同名函數:
#ifdef UNICODE
#define _tcscpy wcscpy
#else
#define _tcscpy strcpy
#endif
_tcscpy
在編譯時會根據條件被替換,
如果是 非UNICODE 工程,它就被替換為 strcpy
UNICODE 工程被替換為 wcscpy
下是使用strcpy_s與strcpy的安全性比較
char szBuf[2] = {0};
strcpy_s(szBuf, 2, "12131"); //新的CRT函數
strcpy(szBuf, "12131"); //老的CRT函數
上述代碼,明顯有緩沖區溢出的問題。 使用strcpy_s函數則會拋出一個異常。而使用strcpy函數的結果則未定,因為它錯誤地改變了程序中其他部分的內存的數據,可能不會拋出異常但導致程序數據錯誤,也可能由於非法內存訪問拋出異常。
使用新的增強安全的CRT函數有什么好處呢?簡單地說,新的函數加強了對參數合法性的檢查以及緩沖區邊界的檢查,如果發現錯誤,會返回errno或拋出異常。老版本的這些CRT函數則沒有那么嚴格的檢查與校驗,如果錯誤地傳輸了參數或者緩沖區溢出,那么錯誤並不能被立刻發現,對於定位程序錯誤也帶來更大困難。