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

时间:2012-11-25 12:08:58

标签: c++ compiler-errors unsafe 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());
     }
}

5 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:5)

如果您查看ctime的说明,请注意:

  

此函数返回指向静态数据的指针,并且不是线程安全的。此外,它还修改了静态tm对象,它可以与gmtime和localtime共享。 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';
}

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

答案 2 :(得分:5)

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

答案 3 :(得分:2)

由于两个原因,

std::ctime不是线程安全的:

  • 它可以修改由多个函数共享的std::tm类型的全局对象。
  • 它修改全局char数组并返回指向该数组的指针。

如果您有其他线程调用std::gmtimestd::localtimestd::ctime,则可能会发生冲突。

要做的最好的事情是将该来电转换为std::ctime来调用std::strftime。这与POSIX一致,后者认为ctime已过时,建议使用strftime

答案 4 :(得分:0)

vs 2017:

.navbar {
    z-index:99;
}

但无论如何你都会收到:

.... cpp(31):警告C4996:&#39; localtime&#39;:此函数或变量可能不安全。请考虑使用localtime_s。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。有关详细信息,请参阅在线帮助。

以防止您可以使用:

#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;
}

普通C部分来自MSDN ......旧方式..