Thread: exception and global variable

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    exception and global variable

    Hello everyone,


    Bjarne mentioned in his book, that there is no way to catch exceptions from the initialization of global variables (section 14.7). But I do not think it is true, because we can add function try block to its constructor, and catch appropriate types of exceptions or using catch(...) to catch all exceptions.

    Am I correct? Any comments?


    thanks in advance,
    George

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, but it's not guaranteed, as it only works if:
    1. You are providing the constructor (and write appropriate code).
    2. The throw happens inside something called by the constructor, and not as part of the runtime initialization "before main" itself.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    I agree with (2). What do you mean (1) -- "are providing the constructor"? Means I owns the code (can access and modify) of constructor?

    Quote Originally Posted by matsp View Post
    Yes, but it's not guaranteed, as it only works if:
    1. You are providing the constructor (and write appropriate code).
    2. The throw happens inside something called by the constructor, and not as part of the runtime initialization "before main" itself.

    --
    Mats

    regards,
    George

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, you need to own (and be able to arbitrarily modify) the source of the constructor.

    The next question is of course what you actually DO if you catch an exception during construction of a global object... Not an entirely easy one to solve, unless you just "log it and exit".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Besides, a constructor function try block cannot swallow exceptions.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You mean that a constructor is not allowed to accept a thrown exception without also forwarding it to the next level down the call-stack?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Correct.

    Code:
    void throws() { throw 0; }
    
    struct foo
    {
      foo() try { throws(); } catch(int) {}
    };
    
    int main()
    {
      try {
        foo f;
      } catch(int) {
        std::cout << "Still caught.\n";
      }
    }
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So the solution to the "can't use exceptions in global construction" is to use a (global) pointer that is initialized in main or some such.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User kroiz's Avatar
    Join Date
    Jun 2007
    Posts
    116
    Quote Originally Posted by CornedBee View Post
    Correct.

    Code:
    void throws() { throw 0; }
    
    struct foo
    {
      foo() try { throws(); } catch(int) {}
    };
    
    int main()
    {
      try {
        foo f;
      } catch(int) {
        std::cout << "Still caught.\n";
      }
    }
    mmm, that is strange syntax never seen a constructor, or any other function, like that.
    first I thought you mistyped but when I compiled it, it worked!
    so why when I write the constructor like below the exception is not caught?
    Code:
    void throws() { throw 0; }
    
    struct foo
    {
      foo() { try { throws(); } catch(int) {} }
    };
    
    int main()
    {
      try {
        foo f;
      } catch(int) {
        std::cout << "Still caught.\n";
      }
    }

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Because a normal try block inside a constructor is allowed to swallow exceptions. Only a function try block is not. The reason is that a function try block catches exceptions from embedded sub-object constructors, and if they threw, the object cannot be fully constructed; thus its constructor cannot be allowed to finish normally.
    If there is a try block inside the constructor body, though, all sub-objects have been constructed when it is entered, so it would be permissible to catch exceptions occuring in the try block and doing something different in the catch block, as long as the resulting object is still valid.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User kroiz's Avatar
    Join Date
    Jun 2007
    Posts
    116
    Thanks CornedBee, I understand. Good to know.

  12. #12
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    So great analysis, CornedBee!


    Quote Originally Posted by CornedBee View Post
    Because a normal try block inside a constructor is allowed to swallow exceptions. Only a function try block is not. The reason is that a function try block catches exceptions from embedded sub-object constructors, and if they threw, the object cannot be fully constructed; thus its constructor cannot be allowed to finish normally.
    If there is a try block inside the constructor body, though, all sub-objects have been constructed when it is entered, so it would be permissible to catch exceptions occuring in the try block and doing something different in the catch block, as long as the resulting object is still valid.

    regards,
    George

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    My question is ansered.

    Quote Originally Posted by matsp View Post
    Yes, you need to own (and be able to arbitrarily modify) the source of the constructor.

    The next question is of course what you actually DO if you catch an exception during construction of a global object... Not an entirely easy one to solve, unless you just "log it and exit".

    --
    Mats

    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. life cycle of exception object
    By George2 in forum C++ Programming
    Replies: 43
    Last Post: 02-13-2008, 07:50 AM
  2. Why does C++ need throw()
    By meili100 in forum C++ Programming
    Replies: 19
    Last Post: 11-10-2007, 12:34 PM
  3. Global objects and exceptions
    By drrngrvy in forum C++ Programming
    Replies: 1
    Last Post: 09-29-2006, 07:37 AM
  4. Handling Global Project Wide Exceptions
    By doom in forum C# Programming
    Replies: 0
    Last Post: 09-12-2005, 10:17 AM
  5. const char VS global char
    By COBOL2C++ in forum C++ Programming
    Replies: 2
    Last Post: 09-04-2003, 11:43 AM