I'm not sure how to ask the question so I'll let the code do the talking. :P
Example 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Global value
char returnValue[256] = {0};
// foo function to do awesome stuff
char* foo(const std::string& var)
{
std::string someValue;
// Do something significant
if ( it worked )
{
memcpy(returnValue, someValue.c_str(), someValue.length());
return returnValue;
}
else
{
return 0;
}
}
Example 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// foo function to do awesome stuff
std::string foo(const std::string& var)
{
std::string someValue;
// Do something significant
if ( it worked )
{
return someValue;
}
else
{
return 0;
}
}
Oops! Example 2 will not work if it worked is false. That is, you can't pass back a NULL construct with a string type.
Is there something else I can do here? I need to be able to pass something back (other than a "valid" string) but can't seem to find a tool to use. Any suggestions?
I'd also suggest throwing an exception, as firedraco says, but I think it depends on the situation. For example, in one case for me, returning the string "N/A" made sense. In other cases, returning an empty string was also ok (i.e., string with 0 length). It depends on what the calling function excepts.
With char's is actually no different. You can return NULL, but if the calling function tried to print it, then you're going to get problems. So the calling function has to handle the case of getting a NULL back.
IMHO, throwing an exception is somewhat more universal since the calling function doesn't have to know what a 0-length string means, etc.
Thank you for your responses. I should have been more verbose about my requirements. I cannot change the interface to how the applications calling this function behave. If I throw an exception they may not handle it.
Currently the application will expect either a character pointer or NULL. I'm updating some legacy code, which was littered with many global variables, to use better techniques and standard containers.
I read values in from a CSV file and report back the corresponding value to the record the application requested. Passing back "" is valid as the CSV file may have "" as the value for the given record. I can't use any valid string as it may be the actual value of the record. "NOT_VALID", "N/A"...all of these are possible REAL values I can have in the CSV file.
I'd love to be able to change the interface or throw an exception (or both) but sadly these are not options for me.
Regarding the length of the character array - based on our technical documents they should never be larger than 19 (maybe it was 26, I forget exactly). In either case there is no threat of a memory issue there.
In this particular case there isn't much way around it... you'll have to have a static storage space somewhere for the return values. You can keep it in the global space if you like, but you can also put it in the function scope thus:
1 2
#include <algorithm>
#include <string>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
char* foo(const std::string& var)
{
staticchar returnValue[256] = {0};
std::string someValue;
// Do something...
if ( it worked )
{
return std::char_traits<char>::copy(returnValue, someValue.c_str(), std::min(sizeof(returnValue)-1, someValue.length()));
}
else
{
return NULL;
}
}
Would it be possible for you to have an error variable (a global one) and return some valid string in the else case ?? The calling function could make a check if the error variable is set and then it might decide if the valid string is actually valid or not ...