Thread: calling functions and error messages

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    630

    calling functions and error messages

    Hello

    Suppose I have some class member function bool read_config_file(); which returns true if the file was read and false if there was an error.

    I've been wondering what would be the best way so that caller could know why the operation failed. One way would be to throw an exception with a proper message (but I dont like to throw exception in this because shouldnt terminate the application) and the next approach I can come up with it would be to return int or enum with error code.

    How do you guys solve that kind of problems? Can someone give some examples of what you think its best?

    Many thanks!

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Throw an exception, catch it in the caller and handle it there.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It sort of depends on:
    1. the severity of the error.
    2. the source of the error (programmer error [e.g. dividing by a number which turns out to be zero because of some math error in the previous calculations], user error [e.g. entering the name of a file which doesn't exist] or system error [e.g. out of memory because of some other application "eating" all the systems memory]).
    3. What you can actually do at the time, and what you can do later one to resolve/report the error.

    In some cases, the best approach is to stop now, in other cases, it's better to continue and report the error later. If you can't allocate memory, and the code following expects the memory to be there [and it couldn't possibly cope with it not being there], you may just as well throw the emergeny brake on and stop there.

    Throwing an exception, by the way, doesn't have to stop the application. If the next level of code knows how to handle the exception, then you can just deal with it and (for example) try again.

    Example:
    Code:
    void someFileFuncion(string filename)
    {
        ifstream fin(filename.c_str());
        if (!fin) throw FileException(string("Could not open file: ") + filename);
        ... // other processing. 
    }
    
    void dofilestuff()
    {
        string filename;
        bool failed;
        do 
        {
           failed = false;
           try {
              cout << "Enter file:";
              cin >> filename;
              someFileFunction(filename);
           } 
           catch(FileException e)
           {
             cout << e.message; 
             cout << "Please enter a valid filename\n";
             failed = true;
           }
        } while (failed);
    }
    --
    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.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    630
    Thank you matsp for this helpful demonstration!

    I have some considerations regarding my read_config_file() function design which looks like:

    Code:
    bool read_config_file(std::string filename) {
    	client_options config;
    
    	std::ifstream ifs(filename.c_str(), std::ios::binary);
    	if (!ifs.is_open()) throw FileException(string("couldnt open file"));
    
    	boost::iostreams::filtering_istream in;
    	in.push(ifs);
    
    	boost::archive::text_iarchive archive(in);
    	archive & config;
    	ifs.close();
    }
    The problem is that boost::archive::text_iarchive can throw as well so should I probably catch std::exception instead? Or maybe it would be better to catch exceptions in read_config_file function and then re-throw FileException or something? What do you think?

    Many thanks for help!

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    If the program can continue after not being able to read the config file, and what the caller does thereafter is not dependent on why reading the config file failed, I would suggest catching any exceptions within the read_config_file method and returning false.

    JMHO, YMMV, etc.

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    630
    What do others think?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Exceptions are very expensive. The best approach, if you ask me, is to allow both kinds of behavior depending on what you need.
    If it's a chain code (ie, the following code needs the previous to be successful), then an exception can save you pain of goto and multiple code duplication on failure.
    If the code will do the operation many times, or is not chain code, consider returning an error.
    Last edited by Elysia; 07-27-2008 at 01:15 PM.
    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
    May 2006
    Posts
    630
    What do you mean by 'expensive'? That they affect program's preformance?

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, they take a long time to execute.
    Throw an exception in a loop and see how many times you can loop before it comes slow. Then compare it when simply returning something and you'll see what a huge difference it makes.
    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.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I'd assume that read_config_file is not called very often, though, so this shouldn't matter.

    I think, generally you should be able to recognize which parts of the program need to perform well and where it doesn't matter and not worry about small performance degradations in the latter parts if that makes the code simpler.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed