victor1234
victor1234

Reputation: 921

How to retrieve error from function?

Suppose I need to get value from config.

What function is more correctly?

int ret;
string value = config.getStringValue(string name, &ret);

or

string value;
int ret = config.getValue(string name, &value);

or maybe

string value = config.getStringValue(string name);
int ret = config.getResultCode();

And what var name for result code is more correctly: ret, error, etc?

Update: Additional to @computerfreaker's comment: there is no exceptions in same platforms like bada

Upvotes: 0

Views: 119

Answers (3)

LihO
LihO

Reputation: 42083

The way you think is: "I have to send some status code to the caller"... this is the way you usually handle errors in C, but since there are exceptions in C++, it's much cleaner and wiser to do:

#include <exception>
std::string getValue() {
    if (...)
        throw std::exception("Unable to retrieve value.");
}

and caller would do:

try {
    std::string val = getValue();
} catch (std::exception& e) { ... }

Just remember the rule: Throw by value, catch by reference.


Regarding "exceptions are meant for handling exceptional states" - it's true. Exceptions should be used in situations when something unexpected / exceptional happens. If function getValue relies on the fact that the value exists and it can be retrieved, then the situation when your code for some reason fails to retrieve this value is exceptional and thus suitable for handling it using exceptions.

Upvotes: 2

Christian Hackl
Christian Hackl

Reputation: 27528

C++ offers several ways of reporting errors from functions which return a value:

  1. Throw an exception. This should be done when the cause of the error is with some external resource and does not normally happen. Perfect example: out of memory.

  2. Return a special value to indicate failure, and follow this convention at the call site. For example, return "" for errors and have callers check for "".

  3. Use std::optional or a similar technique. That's an advanced version of your first example. The basic idea is to return a special object which contains the original object and a boolean flag indicating success. The special object is used with the rule that the original object may only be accessed if the boolean flag indicates success. Other names of this idiom which I've heard are "Fallible" and "Box". This solution and the previous one are good candidates when error cases are expected and frequent -- usually a perfect match for user input.

  4. Abort the program with assert. This is a good solution if an error indicates that your own code is wrong. In this case, the best thing to do is usually terminating the program as quickly as possible before it can do any harm.

  5. Use global error state and have callers check it. That's your third example. C code fancies doing that a lot with errno. In C++, however, this is typically not considered a good solution. It's bad for the same reasons that any kind of global variable is typically bad.

  6. Do not return the value itself but make it an out parameter with a reference. Return an error flag instead. That's your second example. It is better than the previous approach but still very C-like. I would not recommend doing it because it will force callers to name every received value.

Upvotes: 1

Manu343726
Manu343726

Reputation: 14174

Neither solutions you proposed are the correct C++ way. What you provided is just C. In C++, use exceptions

Upvotes: 3

Related Questions