错误C4996:'ctime':此函数或变量可能不安全

7 c++ unsafe compiler-errors ctime

我有一个关于静态源代码分析的大型项目,一切都成功编译,除了一件事.我在标题中提供了错误消息.令我困惑的一点是,它给出了一条错误信息,说不安全.我认为应该只是警告,而不是错误.顺便说一下,我正在使用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());
     }
}
Run Code Online (Sandbox Code Playgroud)

Som*_*ame 8

如果您确定代码中没有安全问题,则可以禁用此功能#pragma warning(disable : 4996).


Mat*_* M. 8

如果你看一下ctime的描述,你会注意到:

此函数返回指向静态数据的指针,并且不是线程安全的.另外,它修改了可以与gmtime和localtime共享的静态tm对象.POSIX标记此功能已过时,建议使用strftime.

行为可能未定义的time_t的时间超过25个字符(如一年10000)导致字符串中的值

......这是很多值得担心的事情.

另一方面,如果你看看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';
}
Run Code Online (Sandbox Code Playgroud)

这更好,因为您不再需要担心可能的缓冲区溢出.

  • 请注意,“std::localtime”还返回指向静态数据的指针,并且可能不是线程安全的,因此这仅修复了可能的缓冲区溢出。 (2认同)
  • 对于VS 2017构造函数来说有点改变了:std :: time_t const now_c = std :: time(NULL); (2认同)

小智 5

是的,它应该只是警告,而不是错误.要获得简单警告而不是错误,请在VS项目中禁用SDL检查(在"配置属性" - >"C/C++" - >"常规"选项卡中).