2

I have some class with Load() function, for example.

class DB {
private:
    pt_db *db;
public:
    DB(const char *path);
    Write(const char *path);
    int Load(const char *path);
};

And I want to return some status from Load() function depending on the passed argument.

For example:

Load(<correct path to the file with valid content>) // return 0 - success
Load(<non-existent path to file>) // return 1
Load(<correct file path, but the content of the file is wrong>) // return 2

Nevertheless also I'm worrying about:

  1. Type safety - I mean I want to return some object which could only be used as status code.

    int res = Load(<file path>);
    
    int other  = res * 2; // Should not be possible
    
  2. Use only predefined values. With int I can return, by error, some other status like return 3 (let's suggest something wrong has happened in Load() function) and if I don't expect this error code will be passed:

    int res = Load(<file path>);
    
    if(res == 1) {}
    
    else if (res == 2) {};
    
    ...
    
    // Here I have that code fails by reason that Load() returned non-expected 3 value
    
  3. Use best C++11 practises about it.

Could anyone help?

5
  • 4
    Will enum class do this? Commented May 29, 2013 at 15:56
  • 2
    Exceptions are the usual way to signal failure. They have the advantage that you can't (accidentally) ignore them and assume success, and they can encode as much information as you want. Commented May 29, 2013 at 15:58
  • I just want to know some of possible solutions. Why C++11 has std::error_code? Also I suggest that this code could be used in C code and C can't handle exceptions. Commented May 29, 2013 at 16:03
  • @user966467, your'e gonna have to wrap it anyway to use it in c... Commented May 29, 2013 at 16:04
  • @user966467: error_code is used by the standard library to report system errors in a standardised way, by throwing a system_error which contains an error_code. Also, you can't use the code directly from C since C can't handle classes either. Commented May 29, 2013 at 16:37

1 Answer 1

3

Enums would be a good way to return status for example:

class Fetcher{
public:
 enum FetchStatus{ NO_ERROR, INVALID_FILE_PATH, INVALID_FILE_FORMAT };
private:
 FetchInfo info;
public:
 FetchStatus fetch(){
    FetchStatus status = NO_ERROR;
    //fetch data given this->info
    //and update status accordingly
    return status;
 }
};

Another way would be to use exceptions

class Fetcher{
private:
 FetchInfo info;
public:
 void fetch(){
    if file does not exist throw invalid file path exception
    else if file is badly formatted throw invalid file format exception
    else everything is good
}

Using enums as return status is more C way and using exceptions might be more C++ way, but its a matter of choice. I like the enum version as it is less code and more readable in my opinion.

Sign up to request clarification or add additional context in comments.

3 Comments

There is also possible to add __attribute__((warn_unused)) (in gcc and clang at least) to result of function ensuring that the return code is not silently ignored. Unfortunately the C++ exceptions are not checked so it is still possible to get something wrong (there is RAII but it protects mostly against resource allocation - there might be more subtle problems caused by terminated code).
Is mixing exceptions and error code acceptable practice? For example throw exception from DB constructor and if Load() fails return error code as in this case I just will not update internal object data and it will point to the old data at when object was created?
Its totally up to you, that isn't a bad idea necessarily, although consider sticking with a consistent approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.