Thread: unexpected behavior of std::current_exception()

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445

    unexpected behavior of std::current_exception()

    I have the following program:

    Code:
    #include <iostream>
    #include <exception>
    #include <stdexcept>
    
    class ExceptionDetector
    {
      public:
        ~ExceptionDetector()
        {
          std::exception_ptr ePtr = std::current_exception();
          if (ePtr) std::cout << "Destroyed while handling an exception." << std::endl;
          else std::cout << "Normal destruction." << std::endl;
        }
    };
    
    int main(void)
    {
      try
      {
        ExceptionDetector detector;
    
        throw std::runtime_error("foo");
      }
      catch (std::exception& ex)
      {
        std::cout << "Exception caught: " << ex.what() << std::endl;
      }
    
      return 0;
    }
    based on the (somewhat vague) description at this link, I'm expecting the destructor to display the message "Destroyed while handling an exception." Unfortunately, this does not seem to be the behavior I'm observing. it always says "Normal destruction."

    am I interpreting the description of that function incorrectly, or is it behaving incorrectly? the gcc C++11 standard library status page doesn't even seem to have an entry for std::current_exception(). I want to have some code only run if the object is destroyed normally, but not if it was destroyed during the stack unwinding process of exception handling.

    Environment:
    Fedora 15 x86_64
    Linux kernel 2.6.38
    GCC 4.6.3

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    By the time your ExceptionDetector is destroyed, the exception you threw has been handled and is out of scope.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by whiteflags View Post
    By the time your ExceptionDetector is destroyed, the exception you threw has been handled and is out of scope.
    that is not the behavior I'm observing though. the ExceptionDetector object is destroyed before the catch block runs. that exception must still exist while the ExceptionDetector destructor is running, which is why I'm confused. is std::current_exception() only intended to be called within a catch block? if so, its usefulness seems quite limited.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    upon closer inspection, it appears that std::uncaught_exception() is intended to do precisely what I'm trying to do.

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    upon closer inspection, it appears that std::uncaught_exception() is intended to do precisely what I'm trying to do.
    Nope.

    What you are trying to do can't be done with portable C++.

    You can try to use such methods, but you are at the mercy of implementers.

    As for `std::current_exception', it is designed to translate the object owned by the exception mechanism, which can be anything, into an object that can be moved to a different, unrelated frame of execution so that exceptions can be "thrown", after a fashion, across unfamiliar frames. In the past, this was ugly at best an impossible on average. So, `std::current_exception' performs exactly as designed.

    In other words, `std::current_exception' is only going to do its job from within a `catch' block. (This is the best guarantee you will receive for portable C++11. It is rather like `std::uncaught_exception' in that regard.) This is mostly because implementations are designed to processes exceptions relative to the exception mechanism.

    The `std::uncaught_exception' function is simply useless in practice. Some compilers always return false regardless of exception state. Do yourself a favor, just don't use it. (The best you can hope for is that it will not fail; it may still like which makes it useless.)

    *shrug*

    Do yourself another favor and explain what you are trying to accomplish. (As opposed to explaining how you'd like to accomplish it.)

    Soma

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I'm not interested in my code being portable. it's a pretty specific application, and gcc seems to implement std::uncaught_exception() correctly, so it fits my needs.

    what I'm trying to accomplish is to locate a bug in a large system that performs transactions on a database. I occasionally have some data getting out of sync, whose relationships cannot be enforced by referential constraints, for reasons beyond the scope of this discussion. the actual class I'm using in my program gets instantiated before the database transaction is started, and gets destroyed after the transaction is committed. it takes a snapshot of certain data before and after the transaction, and inserts an entry in a log if there is a discrepancy. if an exception is thrown while processing the transaction, any changes get rolled back, and I don't want a message to get logged in that case, as I already have exception logging in place. the idea is for the necessary changes to the code to be as non-invasive as possible, and use only the scope/lifetime of the object to determine its behavior. that is, create an object on the stack with certain parameters, and when it is destroyed, it completes its task autonomously.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "std::stringstream" unexpected behavior (simple example)
    By symbiote in forum C++ Programming
    Replies: 2
    Last Post: 11-25-2012, 09:00 PM
  2. Unexpected behavior of stdarg
    By fredb in forum C Programming
    Replies: 2
    Last Post: 01-23-2011, 05:01 AM
  3. scanf/printf unexpected behavior
    By DanV2 in forum C Programming
    Replies: 2
    Last Post: 10-11-2010, 10:23 AM
  4. an unexpected result.
    By System_159 in forum C Programming
    Replies: 7
    Last Post: 01-22-2008, 07:05 AM
  5. unexpected output
    By crash88 in forum C Programming
    Replies: 2
    Last Post: 05-16-2006, 09:03 PM