Thread: The opposite of noexcept

  1. #1
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29

    The opposite of noexcept

    [Edit: The title of this thread should have been "The opposite of noexcept". Sorry about that.] (fixed: Salem)


    I have a variety of Die()-type routines that I use for stack tracing of exceptions and so forth. Typical usage would be something like

    Code:
    int myfunc()
    {
      if (condition)
      {
        return 0;
      }
      else
      {
        Die("error message", HERE);
      }
    }
    Die() builds an exception object from the error message, and from the information in HERE (which is just a macro that expands to __LINE__, __FILE__, __PRETTY_FUNCTION__). It then throws the exception.

    There is of course a problem with this setup. Since myfunc() and Die() are defined in different translation units, the compiler has no way of knowing that Die() always throws an exception. Accordingly (since we're using the -Wall option) it will grumble that the else block of myfunc() doesn't return an int value.

    There are a few simple ways of addressing this, such as:


    1. adding a "throw" statement after Die() in the else block;
    2. putting a default return value at the end of myfunc();
    3. using -Wno-return-value in the compiler options list.


    At first, I didn't like options 1 and 2. So I used option 3 instead. Boy, did I end up regretting that one.

    So now my code is now full of dummy throw and return statements that don't actually do anything (and could act as red herrings during debugging), but which have to be there to keep the compiler from throwing tons of warnings about things that can't happen.

    Is there any way of letting the compiler know that it doesn't need to worry about missing return values from logic branches that contain calls to Die()?

    Equivalently, is there any way of letting the compiler know that Die() always throws an exception? This would be the same as having an "alwaysexcept" specifier, the opposite of "noexcept".
    Last edited by Grumpulus; 04-01-2015 at 03:32 PM. Reason: Thread title clarification

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There is no "always throws" specifier to my knowledge, so I'd just go with 2. What's the problem with one little dummy return statement at the end of the functions?
    Alternatively, you can try putting Die in a header as an inline function, allowing the compiler to see that it always throws.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29
    Quote Originally Posted by Elysia View Post
    Alternatively, you can try putting Die in a header as an inline function, allowing the compiler to see that it always throws.
    That's a really good suggestion. I hadn't thought of that one.

    As it happens, though -- I've been doing a bit more hunting over the past couple of hours -- and found something that is pretty much exactly what I need: the [[noreturn]] attribute.

    That is probably the way I will go.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I suggest you don't use that - it's non-portable between compilers.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Why not re-structure it?
    Code:
    int myfunc()
    {
      if (!condition)
      {
        Die("error message", HERE);
      }
      return 0;
    }
    This is effectively the common idiom of checking for pre-condition violations and returning (or throwing an exception) early, and then when one is certain that the pre-conditions have been satisfied, performing the normal work and returning.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Grumpulus View Post
    ...found something that is pretty much exactly what I need: the [[noreturn]] attribute.
    Quote Originally Posted by Elysia View Post
    I suggest you don't use that - it's non-portable between compilers.
    Compilers may not have support for it yet, but isn't that the new standard-compliant (C++11) way to do it? Clang should support it, as should GCC 4.8 and above. MS Visual C++ does not, and there is no indication that they ever will, as they have their own attribute syntax.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Looking at it now, it is true that it is actually standard. So in the future, all compiler may actually support it. But for now, it's not portable between between VC++ and g++/clang. I'm guessing VC++ will support it sometime in the future.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Jul 2014
    Location
    Calgary, Canada
    Posts
    29
    Quote Originally Posted by laserlight View Post
    Why not re-structure it?
    Code:
    int myfunc()
    {
      if (!condition)
      {
        Die("error message", HERE);
      }
      return 0;
    }
    This is effectively the common idiom of checking for pre-condition violations and returning (or throwing an exception) early, and then when one is certain that the pre-conditions have been satisfied, performing the normal work and returning.
    I actually have another function called DieIf(bool condition, char const* message) that does exactly this.

    (Unfortunately, DieIf() isn't very helpful if the message needs to include more information than a string literal. I did write a DieIf(bool condition, std::string const& message) for that purpose, but then realized that the std::string gets constructed even when the condition is false -- not great for optimization!)

    Basically this is just a convenience issue. As it happens, pretty much everybody in my industry uses GCC, and this particular software is intended for in-house use only, so I'm probably safe using the attribute -- provided of course that documentation of this little caveat appears in the header file where the function is defined.

    My expectation is that this attribute will find its way into other compilers in short order. It's just too useful not to be there.

    Thanks for the feedback everyone.
    Last edited by Grumpulus; 04-06-2015 at 10:52 AM. Reason: Minor clarification

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Grumpulus
    I actually have another function called DieIf(bool condition, char const* message) that does exactly this.

    (Unfortunately, DieIf() isn't very helpful if the message needs to include more information than a string literal. I did write a DieIf(bool condition, std::string message) for that purpose, but then realized that the std::string gets constructed even when the condition is false -- not great for optimization!)
    I am suggesting a restructure of the code that calls Die, not a restructure of Die itself or to change the parameters of Die into DieIf. Consequently, your "isn't very helpful" point and your "not great for optimization" points are not relevant: you can arrange for Die to include whatever other info is needed, and the std::string will only get constructor when the condition is false (or true, as the case may be).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Doing the opposite in a conversion?
    By CplusplusNewb in forum C++ Programming
    Replies: 14
    Last Post: 12-13-2009, 09:01 AM
  2. opposite to atoi() ?
    By Milhas in forum C Programming
    Replies: 5
    Last Post: 03-30-2008, 04:20 PM
  3. opposite to atoi.
    By Mark S. in forum C++ Programming
    Replies: 7
    Last Post: 09-01-2006, 05:11 PM
  4. code is doing the opposite of what i tell it to do..
    By findme in forum C++ Programming
    Replies: 15
    Last Post: 11-24-2005, 01:33 AM
  5. Opposite of sscanf()? Put in, not breakdown.
    By Kleid-0 in forum C Programming
    Replies: 1
    Last Post: 12-26-2004, 10:44 PM