Home > C++11 > The Point Of No Return

The Point Of No Return


As part of learning the new feature set in C++11, I stumbled upon the weird syntax for the new “attribute” feature: [[ ]]. One of these new C++11 attributes is [[noreturn]].

The [[noreturn]] attribute tells the compiler that the function you are writing will not return control of execution back to its caller – ever. For example, this function will generate a compiler warning or error because even though it returns no value, it does return execution control back to its caller:

nr error

nr compile error

The following functions, however, will compile cleanly:

noreturn

Using [[noreturn]] enables compiler writers to perform optimizations that would otherwise not be available without the attribute. For example, it can silently (but correctly) eliminate the unreachable call to fnReturns() in this snippet:

Exec Expired

Note: I used the Coliru interactive online C++ IDE to experiment with the [[noreturn]] attribute. It’s perfect for running quick and dirty learning experiments like this.

Categories: C++11 Tags: , , ,
  1. Chris
    July 22, 2013 at 2:37 am

    `fnForever` isn’t allowed anyway. As of c++11 `while(true);` is ill formed, due to (the first point of) 1.10/24:
    The implementation may assume that any thread will eventually do one of the following:
    — terminate,
    — make a call to a library I/O function,
    — access or modify a volatile object, or
    — perform a synchronization operation or an atomic operation.

    • July 22, 2013 at 5:00 am

      It compiles cleanly under gcc 4.8.1 – which I understand is C++11 feature complete. Try it. Plus, it hasn’t been started as a std::thread.

      Nevertheless, this compiles cleanly:

      [[noreturn]] void fnForever() {
      while(true) ;
      }

      int main() {
      std::thread(fnForever);
      }

      Should I have substituted for(;;) in for while(true)?

  2. Chris
    July 22, 2013 at 5:35 am

    Yes, gcc 4.8.1 is c++11 complete (modulo bugs and standard library). And even if you never create a `std::thread`, or anything else like that, you will always have at least one thread running ( otherwise where is `main()` running? ). This is just one of those odd things the compiler can assume while optimising. It doesn’t have to warn about it, and in fact in general it might not be able to, but in this case it is well within its rights to just remove the `while(true);` entirely. `for(;;);` is no better.
    There’s some discussion here: http://stackoverflow.com/q/3592557/1171191

    • July 22, 2013 at 8:02 am

      Ah, I understand your point now. Perhaps [[noreturn]] is only useful for:

      “Knowing that a function does not return is useful for both comprehension and code generation.” – Bjarne Stroustrup TCPPPL4 12.1.7

      Thanks for contributing Chris.

  3. July 30, 2013 at 10:36 am

    is there any “practical” example? all of the above are in fact something either 1- you won’t see in real app or 2 – you don’t want to see in real app :)

    • July 30, 2013 at 11:32 am

      On P372, Ch13 (Exception Handling) of the 4th edition of TCPPL, Stroustrup uses it in an example to demonstrate program termination where exception handling (for some project or regulatory reason) may not be allowed. Interestingly, “The C++ Primer” 5th edition doesn’t even mention [[noreturn]]. Neither does the second edition of “The C++ Standard Library”.

      In page 30 of the proposal paper for adding the attribute syntax (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2418.pdf), authors Maurer/Wong state:

      “This attribute is useful for a few library functions such as abort and exit which cannot return. The user can also define their own functions that never return using this attribute.
      The noreturn keyword tells the compiler to assume that fatal cannot return. It can then optimize without regard to what would happen if fatal ever did return. This makes slightly better code. More importantly, it helps avoid spurious warnings of uninitialized variables. You cannot assume that registers saved by the calling function are restored before calling the noreturn function. It does not make sense for a noreturn function to have a return type other than void. This is a good attribute because it gives additional information that can be
      used by the optimizer, but does not alter the semantics of the program if removed.”

  1. July 28, 2013 at 1:01 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 439 other followers

%d bloggers like this: