Quick Links:

bal | bbl | bdl | bsl

Component bsla_noreturn
[Package bsla]

Provide a macro to issue a compiler warning if a function returns. More...

Outline
Purpose:
Provide a macro to issue a compiler warning if a function returns.
Macros:
BSLA_NORETURN issue a compiler warning if function returns normally
BSLA_NORETURN_IS_ACTIVE 1 if BSLA_NORETURN is active and 0 otherwise
See also:
Component bsla_annotations
Description:
This component provides a preprocessor macro that annotates a function as never returning, resulting in a compiler warning if a path of control exists such that the function does return.
Macro Reference:
BSLA_NORETURN This annotation is used to tell the compiler that a specified function will not return in a normal fashion. The function can still exit via other means such as throwing an exception or aborting the process.
BSLA_NORETURN_IS_ACTIVE The macro BSLA_NORETURN_IS_ACTIVE is defined to 0 if BSLA_NORETURN expands to nothing and 1 otherwise.
Note that on Windows, the only effect of BSLA_NORETURN is to indicate that the code after a call to a function annotated as such is not executed. On all other platforms where BSLA_NORETURN_IS_ACTIVE is 1, warning messages are also emitted any time code returns from a function annotated with BSLA_NORETURN.
Usage:
This section illustrates intended use of this component.
Example 1: Assertion Handler:
First, we create an assertion handler, myHandlerA, which never returns, and annotate it with BSLA_NORETURN so that the compiler will warn if it does return:
  BSLA_NORETURN void myHandlerA(const bsls::AssertViolation& assertViolation)
  {
      printf("%s:%d %s", assertViolation.fileName(),
                         assertViolation.lineNumber(),
                         assertViolation.comment());

      if      (::getenv("MY_HANDLER_THROW")) {
          throw -1;
      }
      else if (::getenv("MY_HANDLER_EXIT")) {
          ::exit(1);
      }

      ::abort();
  }
Now, a new hire copies myHandlerA and creates a new handler, myHandlerB, that doesn't abort unless instructed to via an environment variable, not realizing that this opens up the possibility of the handler returning:
  BSLA_NORETURN void myHandlerB(const bsls::AssertViolation& assertViolation)
  {
      printf("%s:%d %s", assertViolation.fileName(),
                         assertViolation.lineNumber(),
                         assertViolation.comment());

      if      (::getenv("MY_HANDLER_THROW")) {
          throw -1;
      }
      else if (::getenv("MY_HANDLER_EXIT")) {
          ::exit(1);
      }
      else if (::getenv("MY_HANDLER_ABORT")) {
          ::abort();
      }
  }
Finally, we observe the compiler warning that occurs to point out the possibility of myHandlerB returning:
  .../bsla_noreturn.t.cpp:157:5: warning: function declared 'noreturn' should
  not return [-Winvalid-noreturn]
  }
  ^