advice on try - throw - catch

Discussion in 'C++' started by Gus Gassmann, Jan 29, 2010.

  1. Gus Gassmann

    Gus Gassmann Guest

    I have read a bit about exception handling, but I am still a bit
    unsure of efficiency considerations and things like that. Here is the
    situation:

    string OSInstance::getInstanceName() {
    try {
    if (m_sInstanceName.length() <= 0) {
    if (instanceHeader == NULL)
    throw ErrorClass("instanceHeader object does not
    exist");
    m_sInstanceName = instanceHeader->Name;
    }
    return m_sInstance.Name;
    }
    catch(const ErrorClass& eclass) {
    throw (ErrorClass eclass.errormsg);
    }
    }

    Assume that instanceHeader is nonnull in 999,999 out of 1,000,000
    cases, but in that last case it is really important to warn the user.
    Is the above code efficient? Can the efficiency be improved? Also,
    what happens after the method does catch the error and throws it
    upstairs? Do I have to have another try-catch in the calling routine?
    What if I don't? Would your approach be different in open source and
    closed source code?

    Thanks a million for any feedback.
     
    Gus Gassmann, Jan 29, 2010
    #1
    1. Advertising

  2. Gus Gassmann

    John H. Guest

    On Jan 29, 10:46 am, Gus Gassmann <>
    wrote:
    > if (m_sInstanceName.length() <= 0) {


    From an efficiency perspective, m_sInstanceName.empty() is preferable
    to m_sInstanceName.length()<=0.

    > m_sInstanceName = instanceHeader->Name;
    > }
    > return m_sInstance.Name;


    At one point you mention a m_sInstanceName and at another point you
    mention m_sInstance.Name. I can't tell from code not included, but
    this may or may not be a typo.

    > what happens after the method does catch the error and throws it
    > upstairs? Do I have to have another try-catch in the calling routine?
    > What if I don't?


    Throwing comes from the code that detected the problem. try/catching
    is for the code that wants to know about (or deal with) the problem.

    > if (instanceHeader == NULL)
    > throw ErrorClass("instanceHeader object does not
    > exist");
    > m_sInstanceName = instanceHeader->Name;
    > }
    > return m_sInstance.Name;
    > }
    > catch(const ErrorClass& eclass) {


    Here you throw and then catch right away. This isn't necessary,
    because any code you execute when you caught could just be done
    instead of throwing it to begin with.

    > catch(const ErrorClass& eclass) {
    > throw (ErrorClass eclass.errormsg);
    > }


    When you caught the exception, you immediately threw it again without
    taking any other action. This doesn't serve any purpose because the
    behavior would have been the same if you hadn't caught it at all.

    > what happens after the method does catch the error and throws it
    > upstairs? Do I have to have another try-catch in the calling routine?
    > What if I don't?


    Throwing an exception is a way to indicate to a function further up
    the call stack ("upstairs") that a problem happened. When an
    exception is thrown, it will work its way up the call stack until it
    is caught. If works all the way up and exits main in this way, then
    (depending on the compiler/OS), some message of varying detail may be
    given to the user.
    So if you want to handle the exception in some specific manner (which
    is often the case), then yes, you will want a try/catch in the calling
    routine (or the routine that called that routine, etc.)

    > Would your approach be different in open source and
    > closed source code?


    No.

    I will make up a little example that shows how exception might be used
    in this scenario:

    string OSInstance::getInstanceName() {
    if (m_sInstanceName.length() <= 0) {
    if (instanceHeader == NULL)
    throw ErrorClass("instanceHeader object does not exist");
    m_sInstanceName = instanceHeader->Name;
    }
    return m_sInstanceName;
    }

    void printName(OSInstance & os)
    {
    try
    {
    std::cout << os.getInstanceName();
    }
    catch(const ErrorClass& eclass)
    {
    std::cout << "Unable to print name (" << eclass.errormsg <<
    ")" << endl;
    }
    std::cout << "Have a nice day." << endl;
    }

    int main()
    {
    OSInstance os;
    printName(os);
    return 0;
    }

    Notice in this example, the function that throws the exception didn't
    try to catch it. It was some upstream function that catches it. In
    this case, it was printName. printName prints some error message and
    then continues to run as normal (in this case,print have a nice day
    and then return).

    An alternative could have been:
    void printName(OSInstance & os)
    {
    std::cout << os.getInstanceName();
    std::cout << "Have a nice day." std::endl;
    }

    int main()
    {
    OSInstance os;
    try
    {
    printName(os);
    }
    catch(const ErrorClass& eclass)
    {
    std::cout << "os failed to print name (" << eclass.errormsg <<
    ")" << endl;
    }
    return 0;
    }

    Here notice that if printName() runs and getInstanceName throw the
    exception, the exception will go to printName, who doesn't catch it,
    so the excpetion continues to main(). printName's "Have a nice day
    message" will not get printed.

    Yet another example:

    void printName(OSInstance & os)
    {
    try
    {
    std::cout << os.getInstanceName();
    }
    catch(const ErrorClass& eclass)
    {
    std::cout << "Unable to print name (" << eclass.errormsg <<
    ")" << endl;
    throw ErrorClass(string("Unable to print because ") +
    eclass.errmsg);
    }
    std::cout << "Have a nice day." << endl;
    }

    int main()
    {
    OSInstance os;
    try
    {
    printName(os);
    }
    catch(const ErrorClass& eclass)
    {
    std::cout << eclass.errormsg << endl;
    os.instanceHeader = new InstanceHeader;
    printName(os);
    }
    return 0;
    }

    Here printName catchs the exception, does some action, and then
    rethrows the exception. main then catches it, and can do some more
    actions.

    A final example would be if neither main nor printName has a try/
    catch. Then you would see some default platform specific behavior I
    mentioned previously.

    The examples are just for illustration, not saying they are reasonable
    or correct.
     
    John H., Jan 29, 2010
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jon Maz
    Replies:
    7
    Views:
    4,303
    Jon Maz
    Oct 25, 2004
  2. Matt
    Replies:
    1
    Views:
    414
    Michael Rauscher
    Jun 12, 2004
  3. Chris Riesbeck

    try-catch-throw-finally

    Chris Riesbeck, Jan 19, 2007, in forum: Java
    Replies:
    3
    Views:
    1,046
    Chris Riesbeck
    Jan 22, 2007
  4. Replies:
    8
    Views:
    361
    Matteo
    Dec 5, 2005
  5. dick

    "try{throw}catch"

    dick, Nov 15, 2006, in forum: C++
    Replies:
    7
    Views:
    416
    Noah Roberts
    Nov 15, 2006
Loading...

Share This Page