C

_Noreturn Functions in C

_Noreturn Functions in C

_Noreturn functions in C

C11 added a second function specifier (in addition to `inline') name `_Noreturn', the purpose of this specifier is to inform the user and the compiler that a particular function will not return control to the calling program when it completes execution, informing the user helps to prevent misuse of the function, and informing the compiler may enable it to make some code optimisations.

Just like the `inline' function specifier, _Noreturn is just a hint to the compiler, using it does not stop a function from returning to its caller (it's only a promise made by the programmer to the compiler to allow it some more degree of freedom to generate optimised code), the degree of acceptance is implementation defined.

The `exit' function is an examble of a _Noreturn function, as once it's called, the calling function never resumes. Note that this specifier is different from the void return type, a typical void function does return to the calling function, it just does not provide an assignable value.

If a function with the _Noreturn function specifier violates its promise and eventually violates its promise and returns to its caller (by using an explicit return statement or by reaching the end of the function body) it causes an undefined behaviour, you MUST NOT return from the function. Compilers are encouraged, but not required, to produce warnings or errors when a _Noreturn function appears to be capable of returning to its caller.

Using _Noreturn

The `_Noreturn' keyword appears in a function declaration (and can appear more than once, but its behaviour is the same as if it appeared only once).

You can use the _Noreturn specifier through the convenience macro `noreturn' declared in the header file `stdnoreturn.h' and you can use `noreturn' instead of `_Noreturn', it's the same.

Let's look at an example:

  _Noreturn void
  f ()
  {
    abort (); // This is correct
  }

  _Noreturn void
  g (int i)
  {
    // This will cause an undefined behaviour, as the end of the body can be
    // reached
    if (i > 0) abort ();
  }

And this is how you'd use it with the `stdnoreturn.h' macro:

  #include <stdio.h>
  #include <stdlib.h>
  #include <stdnoreturn.h>

  noreturn void _exit (void);

  void
  _exit (void)
  {
    printf ("Exiting.\n");
    exit (0);
  }

  int
  main (void)
  {
    _exit ();
    return 0;
  }
  int
  f1 (int x)
  {
    int b = 0;

    if (x == 1)
      return 1;

    b = x * f1 (x-1);
    return b;
      }

  int
  main ()
  {
    int n;
    n = f1 (5);
    printf ("%d\n", n);
    return 0;
  }