0

If you throw an unhandled exception out of main like this:

#include <stdexcept>
#include <iostream>
int main()
{
  std::cout << "Hello World 1" << std::endl;
  throw new std::invalid_argument("A");
  return 0;
}

... then the process will terminate with the message "terminate called after throwing an instance of 'std::invalid_argument*'".
You will actually see this on the console:

Hello World 1
terminate called after throwing an instance of 'std::invalid_argument*'

If you print some more text without std::endl and then throw the exception:

#include <stdexcept>
#include <iostream>
int main()
{
  std::cout << "Hello World 1" << std::endl;
  std::cout << "Hello World 2";
  throw new std::invalid_argument("A");
  return 0;
}

... then you won't see the second line on the console:

Hello World 1
terminate called after throwing an instance of 'std::invalid_argument*'

It seems that this error message overwrites the last line, e.g. by printing \r before it.

How can this behavior be fixed?

Niko O
  • 406
  • 3
  • 15
  • How can this ... be fixed? Catch the exception. – Pete Becker Feb 15 '22 at 21:32
  • And... do what with it? That's a rethorical question. Don't catch exceptions that you can't actually handle. The only sensible thing is to terminate the process anyways, so why should I have to waste my time typing out try-catch blocks. – Niko O Feb 16 '22 at 06:46
  • The sensible thing might be to exit normally, with normal output, instead of asking how to hack around the system's error message, which has no portable specification. Cleaning up properly is not a waste of time. – Pete Becker Feb 16 '22 at 13:10

1 Answers1

1

The second line is not actually overwritten by the message, it never reaches the console!

The problem is that std::cout buffers its output and that this buffer is not flushed if the process terminates. (The error message is actually printed to standard error, not standard output.) And that problem was already discovered: Is it possible to make std::cout flush automatically before program termination in various failure cases (e.g., exception)
In my case I used this to forcefully flush the buffer:

std::terminate_handler oldTerminateHandler;

void newTerminateHandler()
{
    std::cout << std::endl;
    if (oldTerminateHandler != nullptr)
    {
        oldTerminateHandler();
    }
}

int main()
{
    oldTerminateHandler = std::set_terminate(&newTerminateHandler);
    //...
}
Niko O
  • 406
  • 3
  • 15
  • If you are reading this and think "Well, this is a pointless post if the problem was already solved on Stack Overflow!", please keep in mind that if you don't already know that the buffering is the problem, you are very unlikely to find that existing question. So the intention here is to give Google something to index that you can find if you don't already know half of the solution. – Niko O Feb 15 '22 at 16:06
  • If you are here because you tried to find out why even writing down the call to some function that crashes causes your `std::cout << "Here!;"` (where you just happened to not have `std::endl` at the end) to not even be executed, then this information should be helpful. I wish I had it when I had that exact problem. I wasted a lot of time and because of this. – Niko O Feb 15 '22 at 16:07