0

I'm building a simple small program for fun, to kill time and learn something. I simply want my program to display local time (I live in Buffalo, NY, so I'm in ET). I put together an ostensibly ridiculous soup of libraries to ensure that my program is aware of everything:

#include <iostream>
#include <chrono>
#include <ctime> 
#include <cstdlib>

#ifdef __unix__
# include <unistd.h>
#elif defined _WIN32
# include <windows.h>
#define sleep(x) Sleep(1000 * (x))
#endif
  1. I tried the code from this page that uses the localtime() method:
#include <ctime>
#include <iostream>

int main() {
    std::time_t t = std::time(0);   // get time now
    std::tm* now = std::localtime(&t);
    std::cout << (now->tm_year + 1900) << '-' 
         << (now->tm_mon + 1) << '-'
         <<  now->tm_mday
         << "\n";
}
  1. I also tried a chunk of code that uses the ctime() method from here > How to get current time and date in C++? :
#include <iostream>
#include <chrono>
#include <ctime>    

int main()
{
    auto start = std::chrono::system_clock::now();
    // Some computation here
    auto end = std::chrono::system_clock::now();
 
    std::chrono::duration<double> elapsed_seconds = end-start;
    std::time_t end_time = std::chrono::system_clock::to_time_t(end);
 
    std::cout << "finished computation at " << std::ctime(&end_time)
              << "elapsed time: " << elapsed_seconds.count() << "s" << 
              << std::endl;
}

Every time I try something, my efforts are accompanied with the compiler stating the following:

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. 15Puzzle    C:\Users\owner\source\repos\15Puzzle\main.cpp   10  

... and when I follow that suggestion, the compiler states that the std library does not have the recommended method. I really don't want to disable anything cautionary.

What should I do?

  • `localtime_s` is not a standard C++ function, so is not in the `std` namespace. It is a Microsoft function that their compiler infuriatingly insists that you use. There is a compiler switch, called out in the error message, that you can use to avoid that error. – jkb Jul 25 '22 at 04:45
  • The compiler is telling you to "use _CRT_SECURE_NO_WARNINGS". Have you tried that? – n. m. could be an AI Jul 25 '22 at 04:49
  • C++20 introduces a set of timezone features to the chrono library. _e.g._ [std::chrono::zoned_time](https://en.cppreference.com/w/cpp/chrono/zoned_time) – paddy Jul 25 '22 at 04:49
  • @n.1.8e9-where's-my-sharem. : But why does it say that? Why don't all libraries and Visual Studio projects already have <_CRT_SECURE_NO_WARNINGS> built into them? And why include something that a user does not even understand to begin with? – AndrewGreen Jul 25 '22 at 04:58
  • @n.1.8e9-where's-my-sharem. : Just tried it. Didn't make a difference. – AndrewGreen Jul 25 '22 at 05:01
  • Microsoft's compiler and Visual Studio really want you to use their `localtime_s` function instead of `localtime` which is why they don't turn on `_CRT_SECURE_NO_WARNINGS` by default. – jkb Jul 25 '22 at 05:16
  • (1) It says that because it wants you to use Microsoft's "secure" functions by default, but provides a recourse for the cases when you don't want to. (2) Having _CRT_SECURE_NO_WARNINGS enabled by default would eliminate the incentive, however small, to use Microsoft's "secure" functions. Since Microsoft's idea of computing is everybody using all things Microsoft's, that's not in Microsoft's best interest. (3) Users are not born with understanding of anything, they are supposed to look up stuff in the documentation. – n. m. could be an AI Jul 25 '22 at 05:25
  • "Just tried it. Didn't make a difference". You are [doing something wrong](https://godbolt.org/z/961hP4W8q), show your code and the exact error message. – n. m. could be an AI Jul 25 '22 at 05:29
  • You need the `#define _CRT_SECURE_NO_WARNINGS 1` line **before** the `#include` lines, IIRC. – Adrian Mole Jul 25 '22 at 05:39
  • Even better as a compiler switch. – Captain Giraffe Jul 25 '22 at 05:52
  • The VS compiler switch (option) to disable it is `/wd4996` – David C. Rankin Jul 25 '22 at 06:03
  • While Adrian Mole's clue certainly solved the problem, and it is my understanding that `_CRT_SECURE_NO_WARNINGS` is essentially a boolean flag used to get around Microsoft/VS compiler's stipulation, what I don't understand is why that stipulation is there. I thought all things `std` and `chrono` came from Microsoft. Why the hindrance? @n.1.8e9-where's-my-sharem. : I introduced `_CRT_SECURE_NO_WARNINGS` in Project Properties > C/C++ > Preprocessor > Preprocessor definitions list as per [this](https://stackoverflow.com/questions/22450423/how-to-use-crt-secure-no-warnings), but that didn't do it. – AndrewGreen Jul 25 '22 at 06:23
  • "I thought all things std and chrono came from Microsoft." No, all things std come from the C++ standard committee that produces the C++ standard. Actually the "_s" functions are in the C standard, but they are optional and no major compiler except Microsoft's implement them, so they are not used very widely. They were added to the standard because Microsoft pushed them. "that didn't do it." Didn't do what exactly? Are you still getting C4996? – n. m. could be an AI Jul 25 '22 at 06:31
  • @n.1.8e9-where's-my-sharem. : I was still getting the C4996 after adding the flag to the list of preprocessor definitions in Project Properties and hitting "Apply". Setting `_CRT_SECURE_NO_WARNINGS` to true at the very top of main.cpp did the trick. – AndrewGreen Jul 25 '22 at 06:48
  • Setting up project properties may be tricky, you need to change it in all build flavours (debug/release/whatever). – n. m. could be an AI Jul 25 '22 at 09:09

1 Answers1

0

(Ideas for the answer were contributed by Adrian Mole and n. 1.8e9-where's-my-share m. in the comments to the OP question.)

The C4996 is simply a stumbling block designed by Microsoft. To bypass this "error", simply set the _CRT_SECURE_NO_WARNINGS flag to true by adding the following to the very top of the main file:

#define _CRT_SECURE_NO_WARNINGS 1

There seems to be more than one theory as to why Microsoft would do this, but the truth is that there's really nothing wrong with using the chrono library's traditional functions.

  • Microsoft *have* explianed this a long time ago. The thought is that the "more secure" versions of the functions are most useful for beginners. And beginners would never get the idea to explicitly enable these warnings. So, to be useful at all, the warnings have to be enabled by default. And then most people turn them off immedietaly, but anyway,,, – BoP Jul 25 '22 at 08:27