Why does "noreturn" function return? Why does "noreturn" function return? c c

Why does "noreturn" function return?


The function specifiers in C are a hint to the compiler, the degree of acceptance is implementation defined.

First of all, _Noreturn function specifier (or, noreturn, using <stdnoreturn.h>) is a hint to the compiler about a theoretical promise made by the programmer that this function will never return. Based on this promise, compiler can make certain decisions, perform some optimizations for the code generation.

IIRC, if a function specified with noreturn function specifier eventually returns to its caller, either

  • by using and explicit return statement
  • by reaching end of function body

the behaviour is undefined. You MUST NOT return from the function.

To make it clear, using noreturn function specifier does not stop a function form returning to its caller. It is a promise made by the programmer to the compiler to allow it some more degree of freedom to generate optimized code.

Now, in case, you made a promise earlier and later, choose to violate this, the result is UB. Compilers are encouraged, but not required, to produce warnings when a _Noreturn function appears to be capable of returning to its caller.

According to chapter §6.7.4, C11, Paragraph 8

A function declared with a _Noreturn function specifier shall not return to its caller.

and, the paragraph 12, (Note the comments!!)

EXAMPLE 2_Noreturn void f () {abort(); // ok}_Noreturn void g (int i) { // causes undefined behavior if i <= 0if (i > 0) abort();}

For C++, the behaviour is quite similar. Quoting from chapter §7.6.4, C++14, paragraph 2 (emphasis mine)

If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined. [ Note: The function may terminate by throwing an exception. —end note ]

[ Note: Implementations are encouraged to issue a warning if a function marked [[noreturn]] might return. —end note ]

3 [ Example:

[[ noreturn ]] void f() {throw "error"; // OK}[[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument <= 0if (i > 0)throw "positive";}

—end example ]


Why function func() return after providing noreturn attribute?

Because you wrote code that told it to.

If you don't want your function to return, call exit() or abort() or similar so it doesn't return.

What else would your function do other than return after it had called printf()?

The C Standard in 6.7.4 Function specifiers, paragraph 12 specifically includes an example of a noreturn function that can actually return - and labels the behavior as undefined:

EXAMPLE 2

_Noreturn void f () {    abort(); // ok}_Noreturn void g (int i) {  // causes undefined behavior if i<=0    if (i > 0) abort();}

In short, noreturn is a restriction that you place on your code - it tells the compiler "MY code won't ever return". If you violate that restriction, that's all on you.


noreturn is a promise. You're telling the compiler, "It may or may not be obvious, but I know, based on the way I wrote the code, that this function will never return." That way, the compiler can avoid setting up the mechanisms that would allow the function to return properly. Leaving out those mechanisms might allow the compiler to generate more efficient code.

How can a function not return? One example would be if it called exit() instead.

But if you promise the compiler that your function won't return, and the compiler doesn't arrange for it to be possible for the function to return properly, and then you go and write a function that does return, what's the compiler supposed to do? It basically has three possibilities:

  1. Be "nice" to you and figure out a way to have the function return properly anyway.
  2. Emit code that, when the function improperly returns, it crashes or behaves in arbitrarily unpredictable ways.
  3. Give you a warning or error message pointing out that you broke your promise.

The compiler might do 1, 2, 3, or some combination.

If this sounds like undefined behavior, that's because it is.

The bottom line, in programming as in real life, is: Don't make promises you can't keep. Someone else might have made decisions based on your promise, and bad things can happen if you then break your promise.