I have a function in a C++ program returning a string.
On certain conditions, e.g. if the function encounters an error or so, I want to return a special value telling the caller that something has gone wrong.
I could basically just return an empty string "", but the function does need the empty string as normal return value.
How can I accomplish this?
Do I have do create a special data structure that for my function that holds a bool if the function was successfully run and a string containing the actual return value?
This sounds like a usecase for exceptions.
try {
std::string s = compute();
} catch(ComputeError &e) {
std::cerr << "gone wrong: " << e.what();
}
If you don't want to or can't use exceptions, you could change the function's interface
std::string result;
if(!compute(result)) {
std::cerr << "Error happened!\n";
}
Though most often, i've seen the return value is used for the actual result, and an error pointer is passed
bool b;
std::string s = compute(&b);
if(!b) {
std::cerr << "Error happened!\n";
}
This has the benefit that you can default the error argument pointer to 0 and code that can ignore the error (because it could live with an empty string return, for example, or if it knows in advance the input is valid) would not need to bother:
std::string compute(bool *ok = 0) {
// ... try to compute
// in case of errors...
if(ok) {
*ok = false;
return "";
}
// if it goes fine
if(ok) {
*ok = true;
}
return ...;
}
You can definitely return a pair, although it is klunky.
pair< string, bool > my_method(...) {
if (a) {
return make_pair(some_value, true);
} else {
return make_pair("", false); // error
}
}
pair< string, bool > result = my_method(...);
if (result.second) {
// success
} else {
// error
}
You can also pass either the bool or the string by reference,
bool my_method(string& s, ...) {
...
}
string s;
if (my_method(s, ...)) {
// success
} else {
// error
}
or:
string my_method(bool& ok, ...) {
ok = false; // default
...
}
bool ok;
s = my_method(ok, ...));
if (ok) {
// success
} else {
// error
}
You could try returning an auto_ptr to a string, but this will cost you an explicit new-ing of a string.
std::auto_ptr<std::string> Foo(int i)
{
if(i == 0) // Error!
return std::auto_ptr<std::string>(NULL);
else // Works.
return std::auto_ptr<std::string>(new string("Hello world!"));
}
If it's really something like an error, you should throw an exception. But by reading your question I guess it's not an "exceptional behaviour"?
If that's the case, you have several non-perfect solutions :
Return a structure with the string and a boolean that tells if the function failed (a simple std::pair<> could be enough).
Make your function modify a string parameter provided by reference and return a boolean telling if the function failed.
Make your function a functor/object that have a state. That state would be (at least) a boolean giving the failure or success of the last function call -- that would then be a function call.
3 is IMO bad design, while 2 and 1 are unperfect compromise.
It depends on how is your program organized.
You may return an additional boolean signifying if the function succeeded. You may return a structure containing boolean and string. You may return a special string (not necessarily empty) which should represent the failure. You may throw an exception. You may set a global flag indicating an error (though I would not recommend it).
There must be lot of other methods to express function failure, too.
The std::pair<> method is good. Another alternative is to have the caller pass the output string in as a non-const reference, and have the function return true or false depending on if an error was encountered or not.
bool Foo(int i, std::string& result)
{
bool ret = false; // no error
// do stuff...
result = "blahbalhbalh";
return ret;
}
Related
What is the idiomatic C++ way of doing this?
I have a method which looks like this:
LargeObject& lookupLargeObject(int id) {
return largeObjects[id];
}
This is wrong, because if you call this with a non-existent id it will create a new instance of large object and put it into the container. I don't want that. I don't want to throw an exception either. I want the return value to signal that object wasn't found (as it is a more or less normal situation).
So my options are either a pointer or an optional. Pointer I understand and like, but it feels like C++ doesn't want to me use pointers any more.
So on to optionals. I will return an optional and then the caller looks like this:
std::optional<LargeObject> oresult = lookupLargeObject(42);
LargeObject result;
if (oresult) {
result = *oresult;
} else {
// deal with it
}
Is this correct? It feels kind of crappy because it seems that I'm creating 2 copies of the LargeObject here? Once when returning the optional and once when extracting it from optional into result. Gotta be a better way?
Since you don't want to return a pointer, but also don't want to throw an exception, and you presumably want reference semantics, the easiest thing to do is to return a std::optional<std::reference_wrapper<LargeObject>>.
The code would look like this:
std::optional<std::reference_wrapper<LargeObject>> lookupLargeObject(int id) {
auto iter = largeObjects.find(id);
if (iter == largeObjects.end()) {
return std::nullopt;
} else {
return std::ref(iter->second);
}
}
With C++17 you can even declare the iter variable inside the if-condition.
Calling the lookup function and using the reference then looks like this (here with variable declaration inside if-condition):
if (auto const lookup_result = lookupLargeObject(42); lookup_result) {
auto& large_object = lookup_result.value().get();
// do something with large_obj
} else {
// deal with it
}
There are two approaches that do not require use of pointers - using a sentinel object, and receiving a reference, instead of returning it.
The first approach relies on designating a special instance of LargeObject an "invalid" one - say, by making a member function called isValid, and returning false for that object. lookupLargeObject would return that object to indicate that the real object was not found:
LargeObject& lookupLargeObject(int id) {
if (largeObjects.find(id) == largeObjects.end()) {
static LargeObject notFound(false);
return notFound;
}
return largeObjects[id];
}
The second approach passes a reference, rather than receiving it back:
bool lookupLargeObject(int id, LargeObject& res) {
if (largeObjects.find(id) == largeObjects.end()) {
return false;
}
res = largeObjects[id];
return true;
}
If default constructed LargeObject is unwanted from lookupLargeObject, regardless of whether it is expensive or it does not make semantic sense, you can use the std:map::at member function.
LargeObject& lookupLargeObject(int id) {
return largeObjects.at(id);
}
If you are willing to live with use of if-else blocks of code in the calling function, I would change the return type of the function to LargeObject*.
LargeObject* lookupLargeObject(int id) {
auto it = largeObjects.find(id);
if ( it == largeObjects.end() )
{
return nullptr;
}
return &(it->second);
}
Then, client code can be:
LargeObject* result = lookupLargeObject(42);
if (result) {
// Use result
} else {
// deal with it
}
I have a function has a return type of std::string& and how do I return a NULL string& if no condition matches in the function?
std::string& SomeClass::getSomething()
{
if(){...}
else if(){...}
// return a NULL
}
C++ references cannot be null.
If you are returning a reference to an object whose lifetime is not tied to the scope of the function call, like a data member, you can safely return a raw pointer (I would recommend a pointer to const).
std::string const* foo::bar() const {
if (condition) {
return &some_data_member;
} else {
return nullptr;
}
}
If not, the best solution is to use a wrapper type like boost::optional (or std::optional in C++17). This not only allows you to return an optional object by value (which may be more performant), but is also self-documenting.
std::optional<std::string> foo::bar() const {
if (condition) {
return "hello, world";
} else {
return std::nullopt;
}
}
Alternatively, you could return a pointer, which can be null. However, returning a raw pointer raises the question of who is responsible for deleting the dynamically allocated string. In this case, returning a std::unique_ptr would be the best option, as ownership is explicitly passed to the caller.
std::unique_ptr<std::string> foo::bar() const {
if (condition) {
return std::make_unique<std::string>("hello, world");
} else {
return nullptr;
}
}
Or even simpler, you could return an empty string, if this is possible in your case. And honestly, this is my preferred approach (KISS).
std::string foo::bar() const {
if (condition) {
return "hello, world";
} else {
return "";
}
}
Anyway you wouldn't return NULL but nullptr.
Also, you should be carefull with returning references from a function and make sure the reference referes to a valid, living object. returning reference to local object is wrong.
you can't return nullptr since nullptr is a pointer and string& is a reference - different types.
your options are:
throw an exception
use something like Optional classes (boost::optional, etc.)
personally, if I know there is a strong possibility the function may fail, I would pass the result to a reference type argument and return bool to indicate success of failure
bool SomeClass::getSomething(std::string& result)
{
if(){result = "success 1"; return true; }
else if(){result = "success 2"; return true; }
return false.
}
Returning the empty string '' might make sense here.
From your code fragment I'd be wondering if you are peeking under the covers of the class to make a decision that the class itself should be making. See the Martin Fowler's article about "Tell, don't Ask" which also refers to the original article on this by The Pragmatic Programmers.
As stated in comments by juanchopanza, you can't.
If you need to test for NULL you could re-think your approach using a smart pointer. For instance a std::shared_ptr<std::string>:
std::shared_ptr<std::string> SomeClass::getSomething()
{
std::shared_ptr<std::string> stringPtr;
if(){
//...
stringPtr = std::make_shared<std::string>("Whatever string goes here");
}
else if(){
//...
stringPtr = std::make_shared<std::string>("The other string...");
}
return stringPtr;
}
Then you could just test the std::shared_ptrwith its implicit conversion to bool:
auto strReturnedPtr = someClassObj.getSomething();
if (strReturnedPtr)
{
// Do stuff
}
When I am using ASSERT_TRUE() provided in Gtest I am getting below error.
return type does not match function type with an underline in VS 2010..
abc.h
#include "gtest\gtest.h"
class abc {
pubilc:
bool fun();
private:
bool fun1();
};
abc.c
bool abc::fun()
{
ASSERT_TRUE(fun1()); // Getting error: return type does not match function type
}
bool abc::fun1()
{
return true; // True or false depanding on operation
}
ASSERT_TRUE is a macro. When expanded it will contain a branch like:
if (fun1() == false) {
return;
}
This is how ASSERT_TRUE does a hard stop on failure, but it also means that your method bool abc::fun() now has a void return exit path, in conflict with its signature.
Possible fixes include don't use hard stop asserts:
bool abc::fun(){
bool result = fun1();
EXPECT_TRUE(result); //No return in expansion
//No hard stop!
return result;
}
or change your methods return type if not needed:
void abc::fun(){
ASSERT_TRUE(fun1()); //Hard stop on failure
}
or return by reference:
void abc::fun(bool &outResult){
outResult = fun1(); //return result by reference
ASSERT_TRUE(result);
}
There is no return statement specified in fun() but it returns a bool. Add a return false; or return true; to fun() or change its return type to void:
void abc::fun()
{
ASSERT_TRUE(fun1());
}
Based on My compiler complains that a constructor (or destructor) cannot return a value. What's going on? which states (verbatim):
Due to a peculiarity of C++, in order to support the syntax for streaming messages to an ASSERT_*, e.g.
ASSERT_EQ(1, Foo()) << "blah blah" << foo;
we had to give up using ASSERT* and FAIL* (but not EXPECT* and ADD_FAILURE*) in constructors and destructors. The workaround is to move the content of your constructor/destructor to a private void member function, or switch to EXPECT_*() if that works. This section in the user's guide explains it.
the return type must be void in functions that use ASSERT_*() macros.
The fun method has a bool return type so it still needs to return something.
ASSERT_TRUE is a macro which tests that something is true, it won't call return for you. In fact, you can have many ASSERT_TRUE in a row, and (providing they are all true) they will all execute one after another. Think of the ASSERT_TRUE macro as a function call, even though it's not technically.
This should work:
bool abc::fun()
{
ASSERT_TRUE(fun1());
return true;
}
I keep on receiving odd unexpected values for my bool testValue. I keep receiving random numbers as I believe it is trying to access another region of memory. I predict it is how my code is setup within my testNumber() function, but I am unsure of how to solve it. This is my logic.
I have set ok to true. Now I assign the memory address of ok to pOk.
void TextBox::lengthTest(bool *pOk, int length) {
bool ok;
if (length < MAX_LENGTH) {
ok = true;
pOk = &ok;
} else {
ok = false;
pOk = &ok;
}
}
bool lengthTestBool = lengthTest(*pOk, length);
cout << lengthTestBool <<;
output:
85
You have a fundamental misunderstanding of how one uses pointers to implement reference semantics. You want to change thing that is pointed to by the pointer:
*pOK = ok;
However, C++ actually supports references semantics natively through reference types, which may be preferable:
void testNumber(bool & OK, int n)
{
OK = true;
// ...
}
Even better, though, is to simply return a bool:
bool testNumber(int n) { /* ... */ }
if (testNumber(x)) //... etc.
I'm using error codes for handling errors in my c++ project. The problem is how to return error codes from a function which is supposed to return some variable/object.
consider this:
long val = myobject.doSomething();
Here, myobject is an object of some class. If doSomething function encounters some error condition then how should it notify the caller (Without using exceptions).
Possible solutions:
Have a data member (say err_) in the class which can be checked by the caller. But it would be unsafe in a multi-threaded application sharing the same object and calling the same function.
Use some global error variable, again same issue in a multi-threaded environment.
Now how can I notify the caller about some error condition?
Make a template called, say, Maybe that it parametrized by your return value type. Whenever you return a value, wrap it in this template like this:
Maybe<long> result = object.somemethod();
The Maybe template would have a way of being instantiated with an error code (probably a static method):
return Maybe<long>::error(code);
But ordinarily would just be returned with the value:
Maybe<long> retval;
retval = 15;
return retval;
(You would have to, of course, override the appropriate constructors, assignment operators, etc.)
In the client side you call a method to check for the error.
Maybe<long> result = object.somemethod();
if (result.is_error)
{
... handle the error ...
}
else
{
... use the result ...
}
Again you'd need the appropriate operators defined to use Maybe<long> wherever there's a long required.
This sounds like a lot of work, but really the work is done once in making a good, bulletproof Maybe template. You'll also have to do some performance tuning on it to avoid nasty overheads. If you want to make it more flexible you can parametrize it on both the return value type and the error type. (This is only a minor increase in complexity.)
You probably want something like Alexandresu's Expected<T> idiom.
You can pass variable as reference and return error code in it.
You can return a std::pair holding both an error code (or error object) and the desired return object. The object of interest needs a default constructor or value so you can return something even when an error is encountered.
It is common to return a return/error code, and make available a property or member with the results.
int retCode = myobject.doSomething();
if (retCode < 0){ //Or whatever you error convention is
//Do error handling
}else{
long val = myobject.result;
}
It is also common to pass in a pointer that is set to the return value, and return the return/error code. (See HrQueryAllRows).
long val = INIT_VAL;
int retCode = myObject.doSomething(&val);
if (retCode < 0){
//Do error handling
}else{
//Do something with val...
}
You have three options:
Create a class containing the return value and a possible error code.
Use something like boost::optional for the return value, which allows
for invalid responses.
Pass a reference to a variable and return any possible error code
within that.
I see there are many nice solutions, but I approach it in another way if I have this situation.
auto doSomething()
{
// calculations
return std::make_pair(error_code, value)
}
int main()
{
auto result = doSomething();
if (!result.first)
{
std::cout << result.second;
}
else
{
std::cout << "Something went wrong: " << result.second;
}
}
For me it's a clean solution than passing bool as reference. auto return type deduction is supported from c++14
Return an error handle. Have an error manager keep the error codes and additional informations (e.g. ERROR_INVALID_PARAMETER and name-value-pairs like ParameterName="pszFileName"). This information can be accessed using the handle. The caller can check the error handle against a NO_ERROR_HANDLE. If true, no error occurred. The caller can augment the error information and pass the handle up the stack.
The error manager can be one for the process or one for each thread.
I would suggest following:
class foo {
public:
long doSomething();
long doSomething(error_code &e);
};
Where error_code is some type that holds error. It may be integer or better something based on boost::system::error_code.
And you supply two functions:
First version throws the error, for example throw boost::system::system_error that is created from boost::system::error_code.
Second returns the error code into e.
The most common practice is to return the error code
long result;
int error = some_obj.SomeMethod(&result);
or return a value that indicate there was an error:
long result = some_obj.SomeMethod();
if (result < 0) error = some_obj.GetError();
In C++17 you use std::optional from the <optional> header:
std::optional<long> myobject = some_func(some_bool);
if (myobject.has_value()) {
// do stuff with myobject.value()
} else {
// myobject has no value
}
// ...
// Example function that returns an optional
std::optional<long> some_func(bool b) {
if (b)
return 15;
return {};
}
define all the error codes in a File. based on error category you can return the error code and the caller can decide what went wrong and caller can return its own error code.
for example
#define FILE_ERROR 1
#define SANITY_ERROR 2
int WriteToFile(char* Data, int iErrorCode)
{
char* FileName;
if (!FileOpen(FileName, &iErrorCode))
{
//Analyze error code and make decision on what to ignore or terminate
iErrorCode = FILE_ERROR;
return 0;
}
}
int FileOpen(char* FileName, int* iErrorCode)
{
if (FileName == null)
{
iErrorCode = SANITY_ERROR;
return 0;
}
///// next code blocks
return 1;
}
I found a new way to do it. It is non-standard and this is an entirely new way to do it.
So consider using this approach cautiously.
Use the following header file:
SetError.h:
#include <string> // for string class
#ifndef SET_ERROR_IS_DEFINED
#define SET_ERROR_IS_DEFINED
class Error {
public:
int code = 0;
std::string errorMessage;
std::string fileName;
std::string functionName;
Error() {}
Error(int _errorCode, std::string _functionName = "", std::string _errorMessage = "", std::string _fileName = "")
{
code = _errorCode;
functionName = _functionName;
errorMessage = _errorMessage;
fileName = _fileName;
}
};
#if defined(_DEBUG) || !defined(NDEBUG)
#define ___try { _ERROR.code = 0; bool __valid_try_mode_declared;
#define ___success }
#define SetError(pErrorData) __valid_try_mode_declared = true; _ERROR = *pErrorData; delete pErrorData;
#else
#define ___try { _ERROR.code = 0;
#define ___success }
#define SetError(pErrorData) _ERROR = *pErrorData; delete pErrorData;
#endif
#endif
inline Error _ERROR;
Include it everyware.
Example of how to use:
Main.cpp:
#include "SetError.h"
#include <iostream>
bool SomeFunction(int value) ___try;
{
if (value < 0) {
SetError(new Error(10, "SomeFunction", "Some error", "File main.cpp"));
return false;
}
return true;
} ___success; // You mast to warp the function with both ___try and ___success
// These keywords must be at the start and the end of the function!
int main()
{
using namespace std;
bool output = SomeFunction(-1);
if (_ERROR.code != 0) { // This is how you check the error code. using the global _ERROR object
cout << "error code: " << _ERROR.code << ", from function: "
<< _ERROR.functionName << ", from file: " << _ERROR.fileName;
}
cout << endl << "Founction returned: " << output << endl;
return 1;
}
If you have some functions that run in another thread, these functions need to be inside namespace and then you can do this:
namespace FunctionsInSomeThread
{
#include "SetError.h"
bool SomeFunc1() ___try;
{
SetError(new Error(5, "SomeFunction2", "Some error from another thread", "File main.cpp"))
return true;
} ___success;
bool SomeFunc2() ___try;
{
SetError(new Error(5, "SomeFunction2", "Some error from another thread", "File main.cpp"))
return true;
} ___success;
}
And to access _Error, you need to add the namespace of the thread
if (FunctionsInSomeThread::_ERROR.code != 0)
{
// Error handling
}
Or in case it is inside the same namespace then no need to add FunctionsInSomeThread:: before.
The idea behind this is that you can't warp the function only with ___success; keyword. You will get compile error. So the developer will never return old error code from another function.
If you wrote ___success; at the end of the codeblock, you must write also ___try; at the start!
You also can't use SetError macro if it is not wrapped in ___try; and ___success;.
The idea come from the AutoIt language where you have this consept:
https://www.autoitscript.com/autoit3/docs/functions/SetError.htm
So this is almost the same in C if you use this header.