error C4996: 'ctime': This function or variable may be unsafe

后端 未结 5 1080
灰色年华
灰色年华 2020-12-09 21:45

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 poi

相关标签:
5条回答
  • 2020-12-09 22:02

    If you look at the description of ctime you will note:

    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.

    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.

    On the other hand, if you look at strftime:

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

    Return value

    number of bytes written into the character array pointed to by str not including the terminating '\0' 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.

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

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

    0 讨论(0)
  • 2020-12-09 22:04

    std::ctime is not thread safe for two reasons:

    • It can modify a global object of type std::tm that is shared by multiple functions.
    • It modifies a global char array and returns a pointer to that array.

    There is a potential for collisions if you have other threads that call std::gmtime, std::localtime, or std::ctime.

    The best thing to do is to convert that call to std::ctime to a call to std::strftime. This is consistent with POSIX, which deems ctime to be obsolete and recommends usage of strftime in its stead.

    0 讨论(0)
  • 2020-12-09 22:18

    If you're sure no safety issues in your code, you can disable this by #pragma warning(disable : 4996).

    0 讨论(0)
  • 2020-12-09 22:19

    Yes, it should be just warning, not an error. To get a simple warning instead of an error, disable SDL check in VS project (in Configuration Properties -> C/C++ -> General tab).

    0 讨论(0)
  • 2020-12-09 22:21

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

    but you will receive anyway:

    ....cpp(31): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

    to prevent you can use:

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

    plain C taken partially from MSDN... old way..

    0 讨论(0)
提交回复
热议问题