繁体   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