I am writing a c-style function:
enum {
EFUNC1,
EFUNC2,
}
int func0() {
int err = 0;
if((err=func1())!=0) {
// return err or return EFUNC1
}
if((err=func2())!=0) {
// return err or return EFUNC2
}
return 0;
}
func1 and func2 are c functions and they have their own error codes. What should I do when func1 or func2 return an error? I figure out some ways:
Design my error codes. The number of error codes is the sum of func1's and func2's. When the call stack is deep, the number of error codes becomes large.
Simply return the result of func1 or func2. There is no way to know which function fails since their error codes may overlap.
Design my error codes and the number of the codes is equal to the number of functions. The caller just know which function return error, but he don't know the further reason.
Throw an exception wrapping the failed function name and its error code.
What's the best practice?
The previous code example is ambiguous. I modified it.
Why expose the complexity of func0() to the caller? Usually the caller is not interested in what happens in the body of the function, he just wants the job to be done.
func0() should notify the user on why it failed to complete its goal (to terminate without errors). They are many ways to do that. One example could be this:
// On success: Return 0
// On error: Return -1
int func0() {
if(func1() == -1) {
printf("Error in func0: func1 returned error code -1");
return -1;
}
if(func2() == -2) {
printf("Error in func0: func1 returned error code -2");
return -1;
}
return 0;
}
Note that here we don't allow func2() to be executed if func1() fails, since that might be dangerous.
For instance, if func1() is suppose to allocate space for an array that func2() is going to use, then let's say that func1() fails (because malloc() failed). func2() should not be called, since func1() failed in that case, because the array that func2() expects to be ready for use, is not available at runtime.
Echoing tobi303's comment, the logic behind error codes is as follows:
If a routine (func0) will fail when an error occurs in a certain subroutine (func1), the routine should stop immediately on error and report back to the caller.
To do otherwise makes no sense. For example, if func0 is to make coffee, func1 is to get some beans and func2 is to brew, then without the beans, you are just brewing air. Telling someone you can't brew air isn't awfully helpful.
If a routine can gracefully handle an error in its subroutine, then its not an error at all for the caller of the routine. In this case, no error should be returned.
So the structure of your program for the first case should be simply
int func0()
{
if(int err = func1())
return err;
if(int err = func2())
return err;
return 0;
}
And the second case
int func0()
{
if(int err = func1())
handle(err);
if(int err = func2())
return err;
return 0;
}
Related
I have some function call like below, and want to print success after success call, but got failure, even the function actually behave correctly.
int myfunction() {
// does some linux sys call for example
int error = run_cmd ("ifconfig usb10 up");
int syserrorno = errno;
strerror(syserrorno);
return error;
}
int main(){
int error =1;
int retry = 0;
do {
error = myfunction();
retry++;
}
while ( error !=-1 && retry <3);
return 0;
}
Basically I tried to:
Run a syscal via myFunction, return error = 1 if fail or 0 if success.
The return error in myFunction is the same as in syscal.
The syscal is a posix spawn command that I reuse from library.
If there is error, print error, redo 3 times.
So I have 1st run of syscall unsuccessfully; it returns error and print out "unavailabe resources". It is expected.
The second time is successful as I check the usb10 and it is up. But it still prints out the same error instead of success.
Is there a way to print it correctly ?
When using errno, always set errno=0; before calling the function(s) whose status you want to check. C library and POSIX functions will set errno to a non-zero value if they encounter an error, but they do not reset it to zero if they succeed.
(The reason they work this way: When a function reporting via errno is actually implemented in terms of other functions, you don't want a later success to make errno forget about an earlier failure. This also makes it possible for user code to set errno=0;, call a number of closely-related library functions, and just check for overall success or failure after all of those calls.)
The problem
I have the following simple situation popping up all over the place. A large number of requests come to the device with a function signature like this:
Err execute( const ICommandContext &context,
const RoutineArguments &arguments,
RoutineResults &results)
There is essentially a request handling server that will call this execute the function for a variety of request types that have these signatures. We have 2 return paths in the case of an error.
The Err output type (consider it to be equivalent to an int) which is used to inform the server or system that something has gone wrong that is to do with the system, not the request. This is always sorted at the top of the function before the user request is dealt with.
RoutineResults provides a setStatus function that can be used to return failure information of the request to the client.
For this reason we have a lot of this type of code popping up:
// Failure due to request
Err error = someFunctionCall(clientInput);
if (!error.success()) {
results.setStatus(error); // Inform the client of the error
return SUCCESS; // Inform the system that we are all good
}
We have a particular request type that has around 15 parameters that come in and are sent off around the system. We would conceptually need 15 of this if error do set which seems wasteful. It is also prone to errors if we need to go through and change anything about how we return. How can we effectively delegate the setStatus and return to a short amount of code that only needs to happen once in the function?
A Macro Solution
A c system might solve this with a macro, something like:
#define M_InitTry Err error
#define M_Try(statement) if (!(error = statement).success()) { goto catch_lab; }
#define M_Catch catch_lab: if (!error.successs())
#define M_Return return error
Which would be used like this:
Err execute( const ICommandContext &context, ...) {
M_InitTry;
...
M_Try(someFunctionCall(clientInput));
M_Try(someFunctionCall(otherClientInput));
...
M_Catch {
// Other specific actions for dealing with the return.
results.setStatus(error);
error = SUCCESS;
}
M_Return;
}
This cleans the code nicely, but is not particularly nice with the goto. It will cause problems if defining variables that might be skipped by a goto.
A delegating solution
I was trying to think of a more C++ so I thought an RAII type delegate might help. Something like:
class DelegateToFunctionEnd {
typedef std::function<void(void)> EndFunction;
public:
DelegateToFunctionEnd(EndFunction endFunction) : callAtEnd(endFunction) { }
~DelegateToFunctionEnd() {
callAtEnd();
}
private:
EndFunction callAtEnd;
};
Pretty simple, it does a delegate of the action until the function return by implementing the action in the destructor. You might use it like this:
Err execute( const ICommandContext &context, ...) {
Err error;
DelegateToFunctionEnd del(std::bind(&RoutineResults::setStatus, &results, std::cref(error)));
error = someFunctionCall(clientInput));
if (error) return SUCCESS;
...
}
Live example.
This solution seems ok, but has several problems:
It is not as clear what is happening.
It is easier to make a mistake about setting error correctly.
You still need a large number of if statements to deal with the returns.
The ability to configure the terminating action is not great.
Dangerous if the user doesn't carefully consider the destruction order of items at function return.
A better solution?
This must be a problem that comes up often. Is there a general solution that provides a clean delegation of this set and returns type action?
I have some unfortunate restrictions below. Don't let these stop you from answering because it might be helpful for future people.
I am working on a c++03 limited system. We have boost, but no c++11.
Embedded system and we have silly rules about exceptions and memory allocation.
If error status codes are proving troublesome, you should consider using exceptions instead. That is, change the API of your functions
so they are guaranteed to have success as a post-condition
throw a suitable std::exception in the event of failure
It is impossible to "forget" to examine a status code if you do this. If you choose not to handle an error condition, the exception thrown by low-level code automatically percolates upwards. You only need to catch a low-level exception if
You need to do some manual roll-back or deallocation in the event of an error,
and RAII is impractical. In this case you would rethrow the expcetion.
You want to translate a low-level exception message or exception type into a high-level message, using a thrown) nested exception.
Maybe, you can write your statement as array, something like:
Err execute( const ICommandContext &context, ...)
{
const boost::function<Err()> functions[] = {
boost::bind(&someFunctionCall, std::ref(clientInput)),
boost::bind(&someFunctionCall, std::ref(otherClientInput)),
// ...
};
for (std::size_t i = 0; i != sizeof(functions) / sizeof(functions[0]); ++i) {
Err err = functions[i]();
if (!err.successs()) {
results.setStatus(err);
return SUCCESS;
}
}
return SUCCESS;
}
and if you do that several time with only different statements,
you might create
Err execute_functions(const ICommandContext &context, std::function<Err()> functions);
Maybe also provide other entry points as OnError depending of your needs.
Split the function.
The inner function returns an error code based on user input; the outer translates that to a client error, and only returns server side errors.
Inner function contains:
if(Err error = someFunctionCall(clientInput))
return error;
repeatedly. Outer has the relay to client error code, but only once.
Err just needs an operator bool. If it cannot have it, create a type that converts to/from Err and has an operator bool.
Can you add a method to error that does the check etc and return a bool.
if(!someFunctionCall(clientInput).handleSuccess(results))
{
return SUCCESS;
}
I need to stop the program flow in the middle, and I am currently using an exception for this. This flow is the legal flow and I want to know if I can do it without using an exception.
This is an example of my code, and I cannot change func_2 and func_1:
#include "stdio.h"
void func_3()
{
printf("i am func_3\n");
throw 20;
printf("i am not supposed to be here\n");
}
void func_2()
{
printf("i am func_2\n");
func_3();
printf("i am not supposed to be here\n");
}
void func_1()
{
printf("i am func_1\n");
func_2();
printf("i am not supposed to be here\n");
}
int main()
{
try
{
func_1();
}
catch (int e)
{
printf("i am supposed to be here\n");
}
catch (...)
{
printf("i am not supposed to be here\n");
}
}
I assume that you want to handle an exceptional case and are looking for an alternative to exceptions. I.e. I hope you don't want to continue with the program "normally" after handling your exceptional case, which is possible but not recommended to implement with exceptions.
Possible but not recommended alternatives to exceptions are:
When you want to stop your whole application, then you can use std::exit(0);. You can implement your "catch"-code in a function which you call instead of your "throw"-statement, and call std::exit(0); at the end of that function (or use another exit code to indicate an "unsuccessful" exit). Or you implement an exit handler and register it using std::atexit(&handle_exit);.
Alternative to std::exit(<something>); is abort(); which throws the POSIX signal "SIGABRT" to indicate abnormal termination (which is the default behavior if your program throws and doesn't catch an exception). Your "catch"-code would then go in a signal handler which you register using the POSIX functions. Note that this requires a POSIX system and is thus not as portable as other solutions.
Another (similar) option is to use the "terminate" mechanism: Call std::terminate(); when you would normally throw your exception. Put your "catch"-code in a "terminate handler" function with signature void(*)(), i.e. no parameters and no return value, let's call the function void handle_terminate(). Install a terminate handler using std::set_terminate(&handle_terminate);. I didn't try that one, however, and it sounds damn ugly.
You could implement an exception-like behavior using assembly instructions, but please do not try this at home, as the behavior of such code is highly implementation defined (if not undefined), and way too ugly to implement.
In short, you can't (well ... you could, by using jumps instead, but then you would have two problems to solve).
The exception solution is the one to use, but do not throw a number (a number - especially a magical number in this case doesn't tell you anything).
Instead, define a struct func_3_interrupted {}; minimalistic structure, whose type name tells you it is an "interruption" of func_3, and catch that instead; The structure should be empty (or close to empty) and it should probably not inherit from the std::exception hierarchy.
Return can be used to return to the caller and stop the function being executed
int GLOBAL_FLAG = 1;
function called_function(){
printf("Inside Function")
if(/*some condition*/)
{
GLOBAL_FLAG = 0;
return;
}
/*Normal function code*/
}
int main(){
{
called_function();
if(GLOBAL_FLAG == 1)/*continue program execution*/
printf("Function had been executed.Back to normal flow")
}
So once the return statement is encountered it goes back to the caller that is main here and continues executing rest of the statements in main function.
I'm using the couple sigsetjmp and singlongjmp with SIGALARM for interrupting a system call, which is illustrated in the following code
//data of Alarm_interrupter
void (TClass::*fpt)(const char*); // pointer to member function
TClass* pt2Object; // pointer to object
===================================================
//for timeout processing
static sigjmp_buf jmpbuf;
static void recvfrom_alarm(int) {
siglongjmp(jmpbuf, 1);
}
======================================================
void Alarm_interrupter::start_timeout() {
signal(SIGALRM, recvfrom_alarm);
alarm(timeout);
(*pt2Object.*fpt)("timeouted before sigsetjmp"); //this call works OK
if (sigsetjmp(jmpbuf,1) != 0) {
//at this point, pt2Object is still OK,
//but fpt seems to point to nothign.
(*pt2Object.*fpt)("timeouted after sigsetjmp");
}
return;
}
==============================================================
Before sigsetjmp returnn 1, the call using object and the method pointer: *pt2Object.*fpt("timeouted before sigsetjmp") is OK, but after sigsetjmp return 1, this call failed.
After examining the state of variables, I noticed that the object pointer "pt2Object" is still Ok, but the method pointer "fpt" seems to different.
I think that one possible reasons for this is that sigsetjmp cannot restore the whole earlier environment, which includes the method pointer "fpt".
Could you guys help me fix this problem. Thanks so much!
As Potatoswatter points out, using the alarm to delay the longjmp is too clever to rely upon. You have to call 'sigsetjmp' first. It has to happen before you try to return there.
The only way sigsetjmp or setjmp will work is following this pseudocode.
if (sigsetjmp(...) != 0) {
// Error handling code
}
// code that might call siglongjmp to bail out to Error handling code
You see, it has to be executed once to perform the save of the context. This initializes the jmpbuf. If you call longjmp without having called setjmp earlier in the execution, the behavior cannot be predicted.
Also, longjmp will tend to obliterate any local variables you might try to use.
int var = 3;
var = 2;
if (sigsetjmp(...) != 0) {
// Error handling code
printf("%d", var); // could print 2, 3 or even "potato". Local vars get trashed.
}
// code that might call siglongjmp to bail out to Error handling code
So you really want to do everything interesting after the *setjmp.
int var = 3;
if (sigsetjmp(...) != 0) {
// Error handling code
var = 2;
printf("%d", var); // now you know it's 2
}
// code that might call siglongjmp to bail out to Error handling code
For any hope of it surviving across the *longjmp, it needs to be marked volatile.
volatile int var = 3;
var = 2;
if (sigsetjmp(...) != 0) {
// Error handling code
printf("%d", var); // probably 2
}
// code that might call siglongjmp to bail out to Error handling code
And even this may not be enough. It may need to be something called a sigatomic_t or something similar. But try not to need crazy stuff like that.
int var = 3;
memcpy(var, (int *){2}); //memcpy is pretty reliable (C99ism: immediate pointer))
if (sigsetjmp(...) != 0) {
// Error handling code
printf("%d", var); // probably 2
}
// code that might call siglongjmp to bail out to Error handling code
I have a rather odd occurrence happening that I haven't been able to nut out yet.
I have test case that is supposed to catch errors and return the appropriate error code from main, but /sometimes/ on test runs the program returns 0 even when the error code is non zero.
The exception class thrown is:
class exit_request {
public:
explicit exit_request(int code = 0) : m_code(code) {}
int code() const { return m_code; }
private:
int m_code;
};
The test case code is:
int main(int argc, char* argv[])
{
try {
// Do some test case stuff
// Eventually, due to the supplied command line arguments,
// we expect an exit_request() to be thrown from within
// library code.
}
catch (exit_request& exp) {
std::cout << "Exit Request:" << exp.code() << std::endl;
return exp.code();
}
catch (std::exception& err) {
std::cout << "Error: " << err.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
In many runs of this test case, everything works as expected: The exit_request() exception is thrown, caught, exp.code() is printed (its value is 2), and the return code from the process is 2.
However, very occasionally, the return code from the process is 0 (i.e. no failure), even though exp.code() is printed as 2.
Can anyone help explain a situation in which this can occur? i.e. the return value from main is changed from non-zero to zero before the process exits?
This is occurring on Windows 7 (x64), with MSVC++ 2010 Express, building a x86 (32-bit) application. I have not seen this odd failure on any of our other Windows or Linux platforms, or compilers, but that doesn't necessarily mean it couldn't happen in those environments.
If you have any atexit handlers that call exit(0), or any static-storage-duration objects whose destructors do that, it might explain what you're seeing. They get executed after your return statement. It's undefined behavior, which could explain why you only see it happen sometimes.
Maybe you are not throwing the exception correctly...
I mean that from the function called or processing done in try block, you are throwing exception of some other type.
Try to write a default catch block for that.