22

Possible Duplicate:
What is the point of the Noreturn attribute?

C11 introduced the _Noreturn attribute to indicate that a function never returns.

Except for documentation value in the source code, what other benefits do the attribute provide, and why would one use it ?

Community
  • 1
  • 1
user1255770
  • 1,572
  • 1
  • 12
  • 18
  • 1
    http://stackoverflow.com/questions/10538291/what-is-the-point-of-the-noreturn-attribute asks the same question for C++. The reasoning for C is exactly the same. – Stephen Canon Dec 03 '12 at 21:47
  • 4
    The reasoning is similar; the syntax appears to be totally different between C++ (`[[noreturn]]`) and C (`_Noreturn` or `noreturn` if you've included ``). So, I'd regard that as a good x-ref; I'm not sure about duplicate, though. – Jonathan Leffler Dec 04 '12 at 07:55
  • 4
    Nominate for reopen because this is about C, and the other is about C++, two completely different languages. The actual syntax is very different as well. – Ciro Santilli OurBigBook.com Sep 17 '14 at 09:40

3 Answers3

26

If a function calls unconditionally a _Noreturn function, the compiler will be able to understand that:

  • the code that follows is dead code, which allows for optimization (it can be removed from the generated binary) and diagnostics - the compiler will be able to emit a "non-reachable code" warnings;

  • most importantly, knowing that the normal flow from the function is interrupted it will be able to avoid spurious warnings about missing return values, uninitialized variables and the like.

    This is particularly important with static code analyzers - the number of false positives given by CLang static analyzer in a biggish application of ours dropped considerably once we marked our die function (log a fatal error and terminate the application) as noreturn.

There may be also some other optimization available - since the function never returns, there's no need to push the return address on the stack, save the state of the registers and whatever, all that's needed is to pass the arguments and do a jmp to the start of the function, without worrying about the return and the post-return cleanup. But of course, since the call is one-shot, the performance to squeeze here is mostly negligible.

Community
  • 1
  • 1
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • by this argument, even a function that returns could be marked as _Noreturn, right?? Ex: `int foo(data * arg) { ++arg->count; return bar(arg); } ` -- function foo could be called with a jump and then jump again to bar() where data is actually returned. Or did I miss the point? – user666412 Aug 24 '15 at 18:49
  • @user666412: that's tail call optimization, which is mostly unrelated. Applying `_Noreturn` to `bar` would mean that it *never* returns; OTOH, here the compiler may just delegate the cleanup to `bar` in just one specific instance. Also, in retrospect my answer puts too much emphasis on the optimization aspect (which is marginal for `_noreturn` functions, as they are obviously rarely called), the point is mostly to mark dead code and better tailor the warnings in the surroundings of such calls (e.g. if I have a function that does `exit(1)` it is irrelevant if it does a return or not). – Matteo Italia Aug 24 '15 at 21:11
  • It still seems too much effort for a call that will happen at most once in a program. – user666412 Aug 25 '15 at 19:02
  • 2
    @user666412: that's what I'm saying, the runtime aspect is mostly negligible. The point is to help the compiler in its code flow analysis and thus produce better warnings; example: in an application of ours there's a `die` function that kills the application logging what went wrong; without marking it as `noreturn` we get quite some spurious warnings about missing `return`s, uninitialized variables and the like - all stuff that disappears once the compiler understands that `die` never returns. – Matteo Italia Aug 25 '15 at 20:19
  • @user666412: reworded the whole answer for clarity and better perspective. – Matteo Italia Aug 25 '15 at 20:23
6

__attribute__((noreturn)) or _Noreturn is useful for functions like die():

static __attribute__((noreturn)) void die(const char *fmt, ...) {
     /* print a formatted error message and exit  */
     exit(EXIT_FAILURE);
}
/* And let's say in main() you would want to exit because of an error but unforunately GCC complains about return value.  */
int main() 
{
    if (!whatever)
         die("a nasty error message goes here\n");
}

And is also used for optimizations as stated.

  • [JFYI] You don't need to explicitly "return" from main() function (this is remnants of C compatibility) – AlexT Feb 03 '14 at 08:22
  • It was just an example to demonstrate what would happen. –  Feb 03 '14 at 08:30
0

It allows additional optimizations to be made by the compiler. Take a look here at GCC's noreturn attribute which it supports for a while now (semantics is probably the same)

Kylo
  • 2,300
  • 1
  • 19
  • 24