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

2021-12-31 00:00:00 compiler-errors c++ unsafe ctime

我有一个关于静态源代码分析的大型项目,一切都编译成功,除了一件事.我在标题中提供了错误信息.让我困惑的一点是它给出了一条错误消息,说不安全.我认为这应该只是警告,而不是错误.顺便说一下,我使用的是 Visual Studio 2012.这是我在 ctime 中遇到错误的代码部分.如果有人能帮助我克服这个错误,我会很高兴.

I have a large project about static source code analysis, and everything compiles successfully, except for one thing. I have provided the error message in the title. The point that confuses me is that it gives an error message saying unsafe. I thought it should be just warning, not an error. By the way, I'm using Visual Studio 2012. Here is the part of the code where I get the error, in ctime. If someone can help me overcome this error, I would be glad.

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());
     }
}

推荐答案

如果看ctime 你会注意到:

这个函数返回一个指向静态数据的指针并且不是线程安全的.此外,它还修改了可能与 gmtime 和 localtime 共享的静态 tm 对象.POSIX 将此函数标记为过时并推荐使用 strftime 代替.

This function returns a pointer to static data and is not thread-safe. In addition, it modifies the static tm object which may be shared with gmtime and localtime. POSIX marks this function obsolete and recommends strftime instead.

导致字符串长度超过 25 个字符(例如 10000 年)的 time_t 值的行为可能未定义

The behavior may be undefined for the values of time_t that result in the string longer than 25 characters (e.g. year 10000)

...有很多事情要担心.

... that's a lot of things to worry about.

另一方面,如果您查看strftime:

On the other hand, if you look at strftime:

size_t strftime( char* str, size_t count, const char* format, tm* time );

size_t strftime( char* str, size_t count, const char* format, tm* time );

返回值

写入 str 指向的字符数组的字节数,不包括成功时的终止符 ''.如果在可以存储整个字符串之前达到计数,则返回 0 并且内容未定义.

number of bytes written into the character array pointed to by str not including the terminating '' on success. If count was reached before the entire string could be stored, ?0? is returned and the contents are undefined.

所有参数都是显式的,因此您可以完全控制可能的数据竞争,并且也不存在提供的缓冲区溢出的风险.

All the parameters are explicit, so that you fully control the possible data races, and there is no risk of overflowing the buffer provided as well.

虽然这是 C 方式,但 C++ 引入了 <chrono>,其中还可以使用特定函数 std::put_time 将时间输出到一个流:

This is the C-way though, and C++ introduces the <chrono> in which a specific function std::put_time can also be used to output time to a stream:

#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") << '
';
}

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

which is even better since you no longer have to worry about the possible buffer overflow.

相关文章