![](/img/trans.png)
[英]c++ - sprintf error “variable may be unsafe” (C4996)… alternatives?
[英]error C4996: 'ctime': This function or variable may be unsafe
我有一個關於靜態源代碼分析的大型項目,一切都成功編譯,除了一件事。 我在標題中提供了錯誤消息。 令我困惑的一點是,它給出了一條錯誤信息,說不安全。 我認為應該只是警告,而不是錯誤。 順便說一下,我正在使用Visual Studio 2012.這是我在ctime中得到錯誤的代碼的一部分。 如果有人能幫助我克服這個錯誤,我會很高興。
void CppCheckExecutor::reportProgress(const std::string &filename, const char stage[], const std::size_t value)
{
(void)filename;
if (!time1)
return;
// Report progress messages every 10 seconds
const std::time_t time2 = std::time(NULL);
if (time2 >= (time1 + 10)) {
time1 = time2;
// current time in the format "Www Mmm dd hh:mm:ss yyyy"
const std::string str(std::ctime(&time2));
// format a progress message
std::ostringstream ostr;
ostr << "progress: "
<< stage
<< ' ' << value << '%';
if (_settings->_verbose)
ostr << " time=" << str.substr(11, 8);
// Report progress message
reportOut(ostr.str());
}
}
如果您確定代碼中沒有安全問題,可以通過#pragma warning(disable : 4996)
禁用此功能。
如果你看一下ctime的描述,你會注意到:
此函數返回指向靜態數據的指針,並且不是線程安全的。 另外,它修改了可以與gmtime和localtime共享的靜態tm對象 。 POSIX標記此功能已過時,建議使用strftime。
對於導致字符串長度超過25個字符(例如10000年)的time_t值, 行為可能未定義
......這是很多值得擔心的事情。
另一方面,如果你看看strftime :
size_t strftime(char * str,size_t count,const char * format,tm * time);
返回值
寫入str指向的字符數組的字節數,不包括成功時終止的'\\ 0'。 如果在存儲整個字符串之前達到count,則返回0並且內容未定義。
所有參數都是顯式的,因此您可以完全控制可能的數據競爭,並且不存在溢出提供的緩沖區的風險。
這是C-way,C ++引入了<chrono>
,其中特定函數std::put_time
也可用於向流輸出時間:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
int main() {
std::time_t const now_c = std::time();
std::cout << "One day ago, the time was "
<< std::put_time(std::localtime(&now_c), "%F %T") << '\n';
}
這更好,因為您不再需要擔心可能的緩沖區溢出。
是的,它應該只是警告,而不是錯誤。 要獲得簡單警告而不是錯誤,請在VS項目中禁用SDL檢查(在“配置屬性” - >“C / C ++” - >“常規”選項卡中)。
std::ctime
不是線程安全的,原因有兩個:
std::tm
類型的全局對象。 char
數組並返回指向該數組的指針。 如果您有其他線程調用std::gmtime
, std::localtime
或std::ctime
,則可能會發生沖突。
最好的辦法是std::ctime
的調用轉換為對std::strftime
的調用。 這與POSIX一致,后者認為ctime
已經過時,並建議使用strftime
。
vs 2017:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
int main() {
std::time_t const now_c = std::time(NULL);
auto s = std::put_time(std::localtime(&now_c), "%F %T");
std::cout << s << std::endl;
}
但無論如何你會收到:
.... cpp(31):警告C4996:'localtime':此函數或變量可能不安全。 請考慮使用localtime_s。 要禁用棄用,請使用_CRT_SECURE_NO_WARNINGS。 詳細信息請參見在線幫助。
防止你可以使用:
errno_t err;
struct tm time_info;
time_t time_create = time(NULL);
localtime_s(&time_info, &time_create);
char timebuf[26];
err = asctime_s(timebuf, 26, &time_info);
普通的C部分來自MSDN ...老方式..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.