I am writing a series of mock functions in C using CMocka
Some of these take pointers as input variables and I am not sure whether I should check them (ptr != NULL) or not.
In general, is the mock function responsible to perform input checking?
If yes, how should it behave when an error is found?
Should it use the assert functions provided by the framework?
If your mentioned pointers are parameters which are passed to some mocked functions you can check them with check_expected(...) and expect_value().
void function_under_test(){
char c = 'c';
int ret;
//...
ret = subfunction(&c);
if(ret == 0)
printf("Success");
//...
}
int __wrap_mocked_subfunction(int* p_paramater){
check_expected(p_paramater);
return mock();
}
test(void **state){
expect_not_value(__wrap_mocked_functions, p_paramater, NULL);
will_return(0);
function_under_test();
}
Errors are then reported automatically.
An example can be found here: https://lwn.net/Articles/558106/
If you really need to check them depends on you and your code and your opinion and your requirements.
Related
I'd like to have access to the $HOME environment variable in a C++ program that I'm writing. If I were writing code in C, I'd just use the getenv() function, but I was wondering if there was a better way to do it. Here's the code that I have so far:
std::string get_env_var( std::string const & key ) {
char * val;
val = getenv( key.c_str() );
std::string retval = "";
if (val != NULL) {
retval = val;
}
return retval;
}
Should I use getenv() to access environment variables in C++? Are there any problems that I'm likely to run into that I can avoid with a little bit of knowledge?
There is nothing wrong with using getenv() in C++. It is defined by stdlib.h, or if you prefer the standard library implementation, you can include cstdlib and access the function via the std:: namespace (i.e., std::getenv()). Absolutely nothing wrong with this. In fact, if you are concerned about portability, either of these two versions is preferred.
If you are not concerned about portability and you are using managed C++, you can use the .NET equivalent - System::Environment::GetEnvironmentVariable(). If you want the non-.NET equivalent for Windows, you can simply use the GetEnvironmentVariable() Win32 function.
I would just refactor the code a little bit:
std::string getEnvVar( std::string const & key ) const
{
char * val = getenv( key.c_str() );
return val == NULL ? std::string("") : std::string(val);
}
If you are on Windows you can use the Win32 API GetEnvironmentVariable
On other linux/unix based systems use getenv
Why use GetEnvironmentVariable in Windows, from MSDN getenv:
getenv operates only on the data
structures accessible to the run-time
library and not on the environment
"segment" created for the process by
the operating system. Therefore,
programs that use the envp argument to
main or wmain may retrieve invalid
information.
And from MSDN GetEnvironment:
This function can retrieve either a
system environment variable or a user
environment variable.
In c++ you have to use std::getenv and #include <cstdlib>
A version of #Vlad's answer with some error checking and which distinguishes empty from missing values:
inline std::string get_env(const char* key) {
if (key == nullptr) {
throw std::invalid_argument("Null pointer passed as environment variable name");
}
if (*key == '\0') {
throw std::invalid_argument("Value requested for the empty-name environment variable");
}
const char* ev_val = getenv(key);
if (ev_val == nullptr) {
throw std::runtime_error("Environment variable not defined");
}
return std::string(ev_val);
}
Notes:
You could also replace the use of exceptions in the above with an std::optional<std::string> or, in the future, with an std::expected (if that ends up being standardized).
I've chosen safety over informativity here, by not concatenating the key into the what-string of the exception. If you make the alternative choice, try and limit copying from key to within reason (e.g. 100 characters? 200 characters?), and I'd also check these characters are printable, and sanitize those characters.
Yes, I know this is an old thread!
Still, common mistakes are, by definition, not new. :-)
The only reasons I see for not just using std::getenv(), would be to add a known default or to adopt common pattern/API in a framework. I would also avoid exceptions in this case (not generally though) simply because a non-value return is often enough a valid response for an environment variable. Adding the complexity of handling exceptions is counter-intuitive.
This is basically what I use:
const char* GetEnv( const char* tag, const char* def=nullptr ) noexcept {
const char* ret = std::getenv(tag);
return ret ? ret : def;
}
int main() {
int ret=0;
if( GetEnv("DEBUG_LOG") ) {
// Setup debug-logging
} else {
...
}
return (-1==ret?errno:0);
}
The difference between this and the other answers may seem small, but I find such small details are very rewarding when you form habits in how you code.
Just like the fact that getenv() returns a non-const pointer, which could easily lead to bad habits!
So, I have a simple library-class and this class has some methods that return some values like code errors.
User_program
MyClass go(arg1, arg2)
if(go.execute() == 0)
std::cout << go.result();
And my class has something like this
My class
int execute()
{
if((temp = doBar()) != 0)
{
return temp;
}
return SUCCESS;
}
int doBar()
{
if(foo == 1)
return DIVIDION_BY_ZERO;
if(fzz == 0)
return OPERATION_ERROR;
}
And so on. So, is there any method to make errors more helpful, I've heard about enum with const for errors, but I don't understand how to implement it.
Thanks.
Not sure that I understood the question right, but here is few moments.
In your case enum`s is way to store all definitions of const
values like (SUCCESS, DIVIDION_BY_ZERO, etc) in one place (even in
one translation unit). And also compiletime validation of types.
read more here:
[1]
2) If intresting how implemented some error check there is no need
to go far.
First of all look at C handling errors in libc [2]
In ISO C++11 presented [system_error]
And typical error handling in libs released special for (almost) each type like in Qt [QNetworkReply]
And also using exceptions(and dark side of C++ like RTTI) in libs is bad idea. But take this link too [3]
This question already has answers here:
GOTO still considered harmful? [closed]
(49 answers)
Closed 8 years ago.
I had a code review recently and a debate began. Much of my code looks like this:
for (i = 1; i <= 3; i++)
{
DoubleValue = tODBCX->getDouble(KeyFieldCount + i, IsNULL, IsSuccess);
if (IsNULL)
{
LoggerDrillHole::LogToDB(LOG_ERROR, L"Survey depth, dip and azimuth values can not be NULL.", __FUNCTIONW__);
IsSuccess = false;
goto EXIT;
}
else
{
if (i == 1)
Depth = DoubleValue;
else if(i == 2)
DipDegrees = DoubleValue;
else if (i == 3)
AzimuthDegrees = DoubleValue;
}
}
The contentious goto statement sparked debate. This code is contained within a function that begins life by initializing a local boolean variable IsSuccess = true and the function finally returns IsSuccess. The EXIT strategy looks after essential tidy up code;
EXIT:
tODBCX->Close();
if (Key != 0) free(Key);
Key = 0;
if (PriorKey != 0) free(PriorKey);
PriorKey = 0;
return IsSuccess;
There were several such goto EXIT statements adjacent to setting IsSuccess = false and logging to database and so on. The comment was made that this is disruptive to the flow of the code. One should instead use a do loop (infinite loop) and break out of that loop and then process all of the required instead of using the goto statement.
I intensely disliked the infinite loop strategy, but I could get used to it if it truly improves the readability. Is there a better way?
I wanted to mark this as a duplicate of this question. Still, it is not exactly the same, even though the solution is the same:
In C++, the best solution is to use RAII and transactional code. In C, the best solution is to use goto, with following a few rules (only use for return/cleanup, do not use goto to simulate loops, etc).
See my answer in the question mentioned above (basically, the solution is to use RAII and transactional code); this will eliminate completely the need for a goto cleanup/error handling block.
There is nothing wrong with using goto here. This is one of the few situations where it is the cleanest solution. (Another example would be breaking out of an inner loop.)
Using a do { ... } while (false) loop is an artificial solution that actually reduces the readability of the code.
In C, consider breaking your code into two functions... an outer function that does common intialisation and passes down the variables the inner function needs, such that the inner function can simply return the success status knowing the outer function will clean up.
In C++ it's usually a good idea to use scope guards so destructors ensure proper clean up. Consider your:
tODBCX->Close();
If tODBCX needs to live longer than the function call - so a Close() in the destructor doesn't help - then create a helper:
struct Odbc_Access_Guard
{
Odbc_Access_Guard(ODBC& o) : odbc_(o) { }
~Odbc_Access_Guard() { odbc_.close(); }
operator ODBC&() { return odbc_; }
operator const ODBC&() const { return odbc_; }
ODBC& odbc_;
};
Then inside your function:
Odbc_Access_Guard odbc(tODBC);
odbc.xyz();
if (whatever)
return ...success expression...;
The same thing goes for your pointers: they should probably be shared pointers or guards using the logic above. Then you can return any time without having to even think about where to go for the clean up code, and wondering if it's up to date with the current variable use.
Should I use parameters to a function as the output? If so, when?
I've seen some WinAPI functions do this, and I don't understand what the reasoning is.
LARGE_INTEGER c;
QueryPerformanceCounter(&c);
...
QueryPerformanceCounter(&c);
Why is a reference used when the code below, seemingly, would do the same? (assuming the function simply returned the result)
LARGE_INTEGER c = QueryPerformanceCounter();
...
c = QueryPerformanceCounter();
Sometimes this is because of an (outdated) concern about the efficiency of returning larger objects by value, but in this case I think the reason was to allow the return value to be used as a status indicating whether the call succeeded or not.
It can be very useful if you want to return an error from the function in order to validate the output:
std::string input;
if(!read_device(input))
{
log("ERROR: reading device:");
return false;
}
// input is valid here
What is a good way to return success or one or more error codes from a C++ function?
I have this member function called save(), which saves to each of the member variables, there are at least ten of these member variables that are saved-to, for the call to save(), I want to find out if the call failed, and if so, on which member variable (some are hard failures, some are soft).
You can either return an object that has multiple error fields or you can use 'out'parameters.
How you do this depends on your design and what exactly you are trying to return back. A common scenario is when you need to report back a status code along with a message of sorts. This is sometimes done where the function returns the status code as the return value and then returns the message status via an 'out' parameter.
If you are simply returning a set of 'codes', it might make more sense to construct a struct type and return that. In that case, I would be prone to pass it in as an out parameter and have the method internally update it instead of allocating a new one each time.
Are you planning on doing this once or many times?
I know this doesn't really answer your question, but...
In C++ you should use exceptions instead of returning error codes. Error codes are most commonly used by libraries which don't want to force the library user to use a particular error handling convention, but in C++, we already have stdexcept. Of course, there might be reasons you don't use exceptions, such as if you're writing embedded code or kernel extensions.
I usually use a boost::tuple:
typedef boost::tuple<int,int> return_value;
return_value r = my_function();
int first_value = boost::get<0>( r );
int second_valud = boost::get<1>( r );
EDIT
You can also use boost::tie to extract the values from a tuple:
boost::tie( first_value, second_value ) = r;
The simplest way to return two values is with the std::pair<> template:
I would use a bitset if you're intention is to purely return error states. e.g.
const bitset<10> a_not_set(1);
const bitset<10> b_not_set(2);
const bitset<10> c_not_set(4);
...
bitset<10> foo(T& a, T& b, T& c, ...)
{
bitset<10> error_code = 0;
...
if ( /* a can't be set */ )
{
error_code |= a_not_set;
}
...
if ( /* b can't be set */ )
{
error_code |= b_not_set;
}
...
// etc etc
return error_code;
}
bitset<10> err = foo(a, b, c, ... );
if (err && a_not_set)
{
// Blah.
}
You need to return them as output parameters:
bool function(int& error1, int& error2, stringx& errorText, int& error3);
You can use an integer with bit manipulation (aka flags).
I probably try to throw an exception first but it depends on your coding paradigm. Please check some books or articles about reasons why c++ exception handling might be better.
If I really need to stick to retrun-error-code style, I would define a eunm type for specifying errors with bit operations..
enum error
{
NO_ERROR = 0,
MEMBER_0_NOT_SAVED = 1,
MEMBER_1_NOT_SAVED = 1 << 1,
MEMBER_2_NOT_SAVED = 1 << 2,
// etc..
};
int save()
{
int ret = NO_ERROR;
// fail to save member_0
ret |= MEMBER_0_NOT_SAVED;
// fail to save member_1
ret |= MEMBER_1_NOT_SAVED;
// ....
return ret;
}
int main(void)
{
int ret = save();
if( ret == NO_ERROR)
{
// good.
}
else
{
if(ret & MEMBER_0_NOT_SAVED)
{
// do something
}
if(ret & MEMBER_1_NOT_SAVED)
{
// do something
}
// check the other errors...
}
}
This is just a rough example. It's better to put this into a class or use a namespace.
I am not familiar with the internals and constrains of your project, but if possible, try to use exceptions instead of error codes.
The reasons are listed here, at C++ FAQ lite, and they conclude with:
So compared to error reporting via return-codes and if, using try / catch / throw is likely to result in code that has fewer bugs, is less expensive to develop, and has faster time-to-market.