Skip to content

Conversation

lyriccoder
Copy link

@lyriccoder lyriccoder commented Sep 17, 2025

Problem description

The destructor of Loop is declared as noexcept(false) and directly calls Stop():

~Loop() noexcept(false) {
    this->Stop();
}

Inside Stop(), there is an unconditional rethrow of a stored exception:

if (curr_exce_) {
    std::rethrow_exception(curr_exce_);
}

This means the destructor may throw exceptions.

Why this is a problem

C++ Standard (ISO/IEC 14882:2017, 18.1, paragraph 7)
If a destructor invoked during stack unwinding exits with an exception, std::terminate() is called.

In other words, if an exception is already in flight and another one is thrown from the destructor, the program will unconditionally crash.

Coding guidelines

  1. CERT C++ [ERR55-CPP]: Do not throw an exception from a destructor.
  2. AUTOSAR C++14 [A15-5-1]: Destructors shall not exit with an exception.

The current implementation directly violates these rules.

Expected behavior

Destructors must not propagate exceptions. They should either:

  • Catch and handle/log exceptions internally, or
  • Guarantee Stop() is noexcept, or
  • Require explicit Stop() invocation by the user before object destruction.

This aligns with the C++ standard, CERT, and AUTOSAR guidelines and prevents hard crashes due to std::terminate().

@lyriccoder lyriccoder changed the title Fix warning Destructor ~Loop() may throw exception (violates C++ standard and guidelines) Sep 17, 2025
@trivialfis
Copy link
Member

It's a real issue, but the fix is quite off ...

@lyriccoder
Copy link
Author

lyriccoder commented Sep 19, 2025

It's a real issue, but the fix is quite off ...

can u suggest the new one? I will rewrite, just do not have the idea how to fix it in another way... @trivialfis Is the updated fix ok for you?

I added a boolean parameter from_destructor to the Stop() method to change behavior based on the caller:
Result Stop(bool from_destructor = false);

How it works:

  1. Normal calls (Stop() or Stop(false)):
  • Preserves original behavior
  • Still throws exceptions via std::rethrow_exception()
  • Maintains existing API contract for users
  1. Destructor calls (Stop(true)):
  • Converts exceptions to Result return values instead of throwing
  • Uses try-catch to safely extract exception information
  • Returns error details through the Result type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants