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)

1

There are 1 best solutions below

0
Ahmed AEK On

your process has an OS buffer called stderr, this is where assert prints to as it is a C function, on the other hand std::cerr is a c++ object that prints text that gets pushed into std::cerr to the stderr buffer.

modifying std::cerr object will change the buffer std:cerr will print to, but it will not modify the underlying OS stderr buffer where assert is printing directly, in order to modify that you need an OS specific function such as freopen or dup2 (whose implementation is defined by the OS, as they are modifying OS buffers)