[LC++]To try or not

George T. Talbot george at phat.com
Sat Sep 28 04:38:01 UTC 2002


The rule that I tend to go by is to use exceptions only for exceptional 
conditions, partially to keep the code readable and partially to keep 
the code fast, as exceptions are slow.

For example, let's say you have a routine that takes a search string, 
and searches a tree:

class TreeNode
{
    public:
        typedef vector<TreeNode> SubNodeContainerType;

        string    name;

        SubNodeContainerType    subNodes;  
};

TreeNode* SearchTree(string& searchString, TreeNode& node)
{
    string    thisToken, restOfSearchString;

    ParseTheSearchString(searchString, thisToken, restOfSearchString);

    if (node.name.equals(thisToken))
    {
        if (restOfString.empty())
        {
            return &node;
        }
        else
        {
            for (TreeNode::SubNodeContainerType::const_iterator    i = 
node.subNodes.first();
                    i != node.subNodes.end();
                    i ++)
            {
                TreeNode*    result = SearchTree(restOfString, *i);

                if (result)
                {
                    return result;
                }
            }
        }
    }
    return 0;
}

As you can see, I wouldn't necessarily use throw to signify "can't find 
this in the tree", but however:

For sake of argument, let's say the search tokens are anything but '/', 
separated by "/":

void ParseTheSearchString(const string& searchString, string& token, 
string& restOfString)
{
    size_type    pos = searchString.find('/');

    if (pos == string::npos)
    {
        if (searchString.empty())
        {
            throw "Can't search--empty search string.";
        }
        token    = searchString;
        restOfString    = "";
    }
    else
    {
        token    = string.substr(0, pos-1);
        restOfString    = string.substr(pos+1);

        if (restOfString.empty())
        {
            throw "Can't search--search string must not end with the '/' 
separator.";
        }
    }
}

You'd call the search routine like this:

    try
    {
        SearchTree("Is/It/In/Here?", someArbitraryTree);
    }
    catch (const char* x)
    {
        cout << "Hey, that was a bad search string: " << errMsg << endl;
        exit(1);
    }

For exceptional conditions--I.E. in this case, invalid input, an 
exception is appropriate and shows good separation between a result 
(found or not found) that's encountered all the time as part of normal 
operation and invalid input.

Anyhow, this is the way I think of these things.

--George


David wrote:

>I'm relatively comfortable with the syntax of exceptions.  The problem I 
>have is I'm still not sure when I should use them.
>
>Is there some standard as too when function should use a return code 
>(ie. return an int) or when it should use exceptions?
>
>I guess what I'm trying to say is, when do I do this:
>
>if (foo() == -1)
>	cout << "Error!" << endl;
>
>And when do I do this:
>
>try {
>	foo();
>}
>catch (int i) {
>	cout << "Error, code: " << i << endl;
>}
>
>
>  
>






More information about the tuxCPProgramming mailing list