I'd like to redirect the output that assert() creates when an assertion fails, so that it is written to a log file instead of the output window. I assumed assert() uses std::cerr to output but when redirecting std::cerr to my log file, assert() still outputs to the output window and not my file:
std::ofstream ofs("log-file.txt");
std::cerr.rdbuf(ofs.rdbuf());
assert(false); // Still outputs "Assertion failed: false" to the output window and not to the log file
I found an SO question with a similar problem and its answer suggested to use freopen instead, like so:
freopen("log-file.txt", "w", stderr);
This gives me an error saying 'freopen': This function or variable may be unsafe. Consider using freopen_s instead.
freopen_s seems to take different arguments than freopen and I can't get it to work.
Another SO answer suggested to use freopen but simply add _CRT_SECURE_NO_WARNINGS to the Command Line in Visual Studio Project Properties. This indeed removed the error and assert() now correctly outputs to my log file.
But this all seems unnecessarily complicated. It feels like there should be a smooth way of achieving what I want to do without suppressing level 3 compiler warnings. Why can't I simply redirect the buffer normally of whatever assert() is using to output? What exactly is assert() using to output, if it's not std::cout, std::cerr or std::clog? (I have tried redirecting all three)
your process has an OS buffer called
stderr, this is whereassertprints to as it is a C function, on the other handstd::cerris a c++ object that prints text that gets pushed into std::cerr to thestderrbuffer.modifying
std::cerrobject will change the bufferstd:cerrwill print to, but it will not modify the underlying OSstderrbuffer whereassertis printing directly, in order to modify that you need an OS specific function such asfreopenordup2(whose implementation is defined by the OS, as they are modifying OS buffers)