错误C4996:“的ctime”:此函数或变量可能是不安全的(error C4996: 'c

2019-07-04 03:25发布

我对静态源代码分析一个大的项目,一切编译成功,除了一两件事。 我在标题中提供的错误信息。 这让我困惑的一点是,它提供了一个错误信息,说是不安全的。 我认为这应该只是警告,而不是错误。 顺便说一句,我使用的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());
     }
}

Answer 1:

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

这个函数返回一个指向静态数据 ,而不是线程安全的。 此外,它修改可能与gmtime的和localtime被共享的静态TM对象 。 POSIX标志着这一功能已经过时,建议改为strftime的。

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

......这是一个很大的事情操心。

在另一方面,如果你看的strftime :

为size_t的strftime(字符* STR,为size_t计数,为const char *格式,TM *时间);

返回值

写入到字符数组字节数指向STR不包括上成功终止“\ 0”。 如果达到计数可以存储整个字符串之前,则返回0和内容是不确定的。

所有参数都是明确的,让你完全控制可能的数据争,并没有提供溢出以及缓冲的风险。

这是C-方式虽然,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';
}

这甚至更好,因为你再也不用担心可能缓冲区溢出。



Answer 2:

如果你确定你的代码中没有安全问题,则可以通过禁用此#pragma warning(disable : 4996)



Answer 3:

是的,这应该只是警告,而不是错误。 为了得到一个简单的警告,而不是错误,禁用VS项目SDL检查(在配置属性 - > C / C ++ - >常规选项卡)。



Answer 4:

std::ctime是不是有两个原因线程安全的:

  • 它可以修改类型的全局对象std::tm由多个功能共用。
  • 它会修改全局char数组,并返回一个指针数组。

没有为冲突,如果您有调用其他线程潜在std::gmtimestd::localtime ,或std::ctime

做的最好的事情就是该呼叫转换std::ctime到调用std::strftime 。 这是与POSIX,它认为是一致ctime过时,且建议的用法strftime代替它。



Answer 5:

2017年VS:

#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_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 ...旧的方式部分地采取了..



文章来源: error C4996: 'ctime': This function or variable may be unsafe