【C語言學習筆記】VS中"This function or variable may be unsafe."警告的解決辦法

原文鏈接:https://blog.csdn.net/u012534008/article/details/54602774

VS中”This function or variable may be unsafe.”警告的解決辦法
問題原因
C語言的標準函數中,一些讀取或寫入內存的函數存在內存越界的問題,從而使得內存數據變得不安全。如scanf、gets、strcat等函數都存在着這樣的問題。 
爲了避免這個問題,在VS中,另外提供瞭如scanf_s,get_s,strcat_s等相關的改進函數,來替代原來的標準函數的功能,並通過添加內存讀取範圍的限制來解決不安全的問題。 
在實際的應用中,也許使用VS提供的安全函數會更加合理。但是,在學習中,幾乎所有的課本以及教程都使用的原來的標準函數,另外考慮到移植性的問題,除了VS環境,其他環境中並沒有提供改進後的函數。因此,我們通常任然需要標準的庫函數來實現相關功能。 
但是,如果在VS中使用原始的函數,編譯器將會報錯。這對使用和學習都帶來了相當的不變。

問題分析
在VS2013中,以scanf爲例。 
如果在程序中使用了scanf函數,如下

#include <stdio.h>
int main()
{
    char c[20];
    scanf("%s", c);
    puts(c);
    return 0;
}


編譯將得到如下錯誤信息。

error C4996: ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 
參見“scanf”的聲明

錯誤信息的大意如下

此函數或變量可能不安全。 
可以使用scanf_s代替該函數。 
如果要取消禁用,請定義_CRT_SECURE_NO_WARNINGS。 
更多信息請查看在線幫助

scanf的聲明如下

_Check_return_ _CRT_INSECURE_DEPRECATE(scanf_s) _CRTIMP int __cdecl scanf(_In_z_ _Scanf_format_string_ const char * _Format, ...);

在scanf的聲明中,在函數的標準形式說明之前,還用到了幾個宏定義,正是因爲這幾個宏定義才實現了scanf函數的禁用。 
在VS中利用F12可以看到這幾個宏的定義,宏定義具體內容如下

sal.h
#define _Check_return_           _SAL2_Source_(_Check_return_, (), _Check_return_impl_)

crtdefs.h  
#define _CRT_INSECURE_DEPRECATE(_Replacement) _CRT_DEPRECATE_TEXT("This function or variable may be unsafe. Consider using " #_Replacement " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.")

crtdefs.h 
#define _CRTIMP __declspec(dllimport)
上面三個宏都包含了宏的嵌套調用,相關宏略多,因此在此不對其進行深入研究。 
不過在第二個宏定義中,我們可以很容易發現在編譯時,編譯器向我們返回的錯誤信息。這進一步說明了scanf函數不能使用與這幾個宏有關。

問題解決
在編譯器給出的錯誤提示中,實際上已經爲我們給出了一個明確的解決方案。我們只需要在程序的開頭添加一個宏定義便能夠解決問題。

#define _CRT_SECURE_NO_WARNINGS


加入宏定義後,源代碼變爲如下形式

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
    char c[20];
    scanf("%s", c);
    puts(c);
    return 0;
}


再次進行編譯,編譯成功完成。

雖然按照上述的方法能夠順利解決問題,但是在實際的應用中,如果我們要求只能夠使用標準庫中的函數,而不能使用VS爲我們提供的改進函數。那麼我們每次在使用到相關函數時,都需要在文件前面,或者在頭文件中添加相關宏。這樣未免太麻煩。 
既然我們不需要VS給我們提供的這個多餘的改變,那有沒有一個一勞永逸的辦法解決這個問題呢。 
方法是有的,這需要我們對VS的項目屬性進行設置,具體步驟如下。

在項目屬性設置中找到選項卡配置屬性→C/C++→預處理器;
在右側的參數中找到預處理器定義,編輯其參數;
在參數的末尾添加定義_CRT_SECURE_NO_WARNINGS
這樣,在編譯器進行預處理時,預處理器就會自動在程序開頭添加我們需要的宏定義,而不再需要我們手動添加。 
在文件中不添加宏定義的情況下,再次進行編譯。發現編譯順利完成。 
這種方案因爲修改的是項目的配置參數,因此適用於整個項目。在該項目中,將不再需要添加相關宏定義。但是其他項目自然不受該設置的影響,因此,如有需要,在其他項目中需要再次進行相同配置才能生效。
--------------------- 
版權聲明:本文爲CSDN博主「夏蒼」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u012534008/article/details/54602774

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章