簡體   English   中英

錯誤C4996:'ctime':此函數或變量可能不安全

[英]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::gmtimestd::localtimestd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM