Home > OS >  How to exit from a called function?
How to exit from a called function?

Time:08-24

I am checking the input arguments provided and if it is not in the range specified, it should exit from the function. Suppose I have called a function, Func(arg). If arg is not in the specified range, the function should return to main().
The code sample is as follows:

#define check_param(expr) ((expr) ? (void)0U : exit(3))
void Func(int arg)
{
  check_param(arg);
  ...
  ...
}

int main()
{ 
  ...
  Func(10);
  ...
  return 0;
}

If I use exit(), it will exit the whole program. I want to return to main() and execute further instructions. I can't use return as it is a statement. What can be used in place of exit(3)?

The above definition is used for both type of functions (void and int type).

CodePudding user response:

Do not hide the return, that's just asking for trouble. Simply replace this part:

#define check_param(expr) ((expr) ? (void)0U : exit(3))
void Func(int arg)
{
    check_param(arg);

with this:

// suggestion: return 0 on success, or error code
int Func(int arg)
{
    if (!arg) return 3; // error code

    ...
    return 0; // no error
}

Using funny macros does not make the code easier to read, and they can be a real head-ache when debugging.

CodePudding user response:

You do not need to use only an expression as the replacement sequence for a macro. It can be a statement (or part of one), such as:

#define check_param(expr)    if (!(expr)) return

Since you want the macro to work in functions that return void and in other functions, we need to give it a way to have a matching return statement, one that either does or does not give a return value, as desired. We can do this with another parameter:

#define check_param(expr, value)    if (!(expr)) return value

Then the macro can be used:

check_param(arg,);       // In function that returns void, value is blank.
check_param(arg, -1);    // In other functions, value is not blank.

Note that in return value, value is not in parentheses. It is usual to enclose macro arguments in parentheses to avoid precedence issues, but that cannot work here because we need return value to work when value is blank, and return (); would cause a syntax error.

Finally, when defining a macro as a statement, there is an idiom to wrap it in a do-while statement so that it acts grammatically like an ordinary statement:

#define check_param(expr, value)    do if (!(expr)) return value; while (0)

Note that, in the original if form, if the macro invocation happens to be followed by an else, like this:

if (A)
    check_param(arg, value);
else
    MyRoutine(arg);

then the else would be associated with the if resulting from the check_param macro instead of with the if (A). By wrapping the macro in do … while, we prevent this sort of undesired interpretation.

CodePudding user response:

  1. I do not see any use of such a macro (maybe to make the code more difficult to read)
  2. I would use statements, not expressions.

This Macro will work both for void (second macro parameter blank after comma) and non void functions. cond and retval can be expressions objects or constants. retval does not have to be in parentheses as it is normally in macros because there are no other operations in this statement.

#define check(cond, retval)  do{if(!(cond)) return retval;}while(0)

int foo(int x)
{
    check(x == 2, x * 2);
    
    /* ... */

    return something;
}

void bar(const char *s1, const char *s2)
{
    check(!strcmp(s1,s2), );
}

https://godbolt.org/z/hY9rKe4xs

Example more real usage:

int div(const int x, const y)
{
    check(y != 0, INT_MIN);

    return x / y;
}

CodePudding user response:

Simply call return inside that function.

function YOUR_FUNCTION(){
   ....
   ....
   return;
}
  •  Tags:  
  • c
  • Related