Sebastien Comtois
Sebastien Comtois

Reputation: 3

Error code with implementation of time_t in C++

time_t rawtime;
struct tm * timeinfo;

time(&rawtime);
timeinfo = localtime(&rawtime);

heure_= timeinfo->tm_hour;
minute_ = timeinfo->tm_min;
seconde_ = timeinfo->tm_sec;
jourMois_ = timeinfo->tm_mday;
jourSemaine_ = timeinfo->tm_wday;
mois_ = timeinfo->tm_mon;
annee_ = timeinfo->tm_year;

This is my implementation for a function that look up the time, the date,.... and so on.

I don`t know why but I get the error:

1>c:\users\sebastien\blabla: warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data

1> DateHeure.cpp

1>c:\users\sebastien\blabla-> error 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.

1> c:\program files (x86)\microsoft visual studio

12.0\vc\include\time.inl(112) : see declaration of 'localtime'

I have tried to change localtime to localtime_s but I get some error message concerning compatibility with parameter of type "tm".

I have also tried to (include or wright) __CRT_SECURE_NO_WARNINGS but with no success -> I don't know but just including this line seems odd (in the properties>c++>preprocessor>undefined preprocessor definitions) without adding anything else.

Acknowledge that I am not that familiar with Visual Studio, so I am not sure with all these properties setting and tweaking.

but I would really appreciate if one could help me with this time thing, I think it's my only error, I'll debug after to be sure.

Please include some information on the why... I'd like to understand.

Upvotes: 0

Views: 4911

Answers (2)

Ben Voigt
Ben Voigt

Reputation: 283644

C4996 isn't supposed to be an error, I suppose you adjusted your compile options to make it one. (Or the project wizard did)

Anyway, the alternate functions that don't use static local buffers ARE better, and they're also portable (in everything except the name, it's localtime_s on Win32 and localtime_r on Linux, which a macro can fix), so there's really no reason not to use them.

The versions without static local buffer expect you to supply a buffer, which is easy:

time_t rawtime;
struct tm timeinfo;  // no longer a pointer

time(&rawtime);

// on platforms with POSIX localtime_r but no localtime_s, add this macro
// #define localtime_s(x, y) localtime_r(y, x)
localtime_s(&timeinfo, &rawtime); // fills in your structure,
                                  // instead of returning a pointer to a static one

heure_= timeinfo.tm_hour;  // no longer using a pointer
minute_ = timeinfo.tm_min;
seconde_ = timeinfo.tm_sec;
jourMois_ = timeinfo.tm_mday;
jourSemaine_ = timeinfo.tm_wday;
mois_ = timeinfo.tm_mon;
annee_ = timeinfo.tm_year;

Upvotes: 5

Retired Ninja
Retired Ninja

Reputation: 4925

The localtime function can be unsafe as the pointer it returns points to a structure that is used for itself and other calls. That means if you call a function that changes that internal structure all the pointers that point to it would reflect the new data.

If you are aware of that you can still use it safely if you can be sure the data won't be modified before you're done with it. In that case you could do something like this:

#define _CRT_SECURE_NO_WARNINGS 1
#include <ctime>
#include <iostream>

int main()
{
    time_t rawtime = time(nullptr);
    tm* timeinfo = localtime(&rawtime);

    std::cout << asctime(timeinfo) << "\n";
    return 0;
}

If you wish to use the more secure localtime_s which populates a structure that you pass in that won't change unexpectedly then you could use it like this:

#include <ctime>
#include <iostream>

int main()
{
    time_t rawtime = time(nullptr);
    tm timeinfo;
    errno_t error = localtime_s(&timeinfo, &rawtime);
    if(error != 0)
    {
        std::cerr << "localtime_s failed.\n";
        return -1;
    }

    std::cout << asctime(&timeinfo) << "\n";
    return 0;
}

Keep in mind that localtime_s may not be available on all platforms so it could be less portable.

Upvotes: 1

Related Questions