Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you "break" out of a function?

Tags:

c++

Given a function that returns a value, is it possible to exit the function given a certain condition without returning anything? If so, how can you accomplish this?

Example:

int getNumber ()
{ 
    . . . 
}

So say you are in this function. Is there a way to exit it without it doing anything?

like image 525
Brandon Tiqui Avatar asked Feb 17 '10 07:02

Brandon Tiqui


People also ask

Can you break in a function?

A function can't break on behalf of its caller. The break has to be syntactically inside the loop. Show activity on this post. You want to use return , not break .

Can you break out of a function in C?

When a break statement is encountered inside a loop, the loop is immediately terminated and the program control resumes at the next statement following the loop. It can be used to terminate a case in the switch statement (covered in the next chapter).

Can you break out of a function Python?

To break out of a function in Python, we can use the return statement. The Python return statement can be very useful for controlling the flow of data in our Python code.

How do you exit a function in C++?

exit function h>, terminates a C++ program. The value supplied as an argument to exit is returned to the operating system as the program's return code or exit code. By convention, a return code of zero means that the program completed successfully.


8 Answers

Alternative of exceptions is return of status code:



SomeStatusCode YourFunc(int &returnValue)
{
    ...
    returnValue = SomeValue;
    return SomeStatusCode.Successful;
    ...
    return SomeStatusCode.Fail;
}

//in main func

   if(YourFunc(retValue)==SomeStatusCode.Successful)
   // work with retValue
   else
   // nothing to do, show error, etc.
</code>
like image 53
zabulus Avatar answered Oct 07 '22 09:10

zabulus


You have two options: return something or throw.

int getNumber() 
{
    return 3;
}

int getNumber() 
{
    throw string("Some Var");
}

If you throw, you have to catch the type you threw.

int maint(int argc, char ** argc)
{
     try
     {
           getNumber();
     }
     catch(string std)
     {
          //Your code will execute here if you throw
     }
 }
like image 45
rerun Avatar answered Oct 07 '22 09:10

rerun


You might get away with a return; with no return value. The compiler will warn, but may not error.

BUT, why on earth would you even consider this? What are you trying to achieve?

And what does the calling code look like? If it is int someVar = getNumber(); then the value of someVar is undefined (which is A Bad Thing).

It sounds to me like you want to return two pieces of information, one of which tells you if the other is valid.

Try something like

bool GetNumber(int * outputNumber)
{
   if ....
   {
      *outputNumber = ...;
      return true;
   }  
   else
   {
      return false; // contents of outputNumber are undefined
   }
}

int number;
bool isNumberValid;
isNumberValid = GetNumber(&number);
if (isNumberValid)
    ... do something with number
like image 23
Mawg says reinstate Monica Avatar answered Oct 07 '22 08:10

Mawg says reinstate Monica


Simple solution:

boost::optional<int> getNumber( )
{
  // May now return an int, or may return nothing.
}
like image 40
MSalters Avatar answered Oct 07 '22 08:10

MSalters


For float and double there is an alternative but not for int types.

#include <limits>

double Get()
{
  // no valid return value
  return std::numeric_limits<double>::quiet_NaN();
}

double val = Get();
if(val != val) {
  // Retrieved no valid return value 
}
else {
  // No NaN retrieved
}

Be careful when using NaN. Each condition on val will be true.

like image 22
Totonga Avatar answered Oct 07 '22 08:10

Totonga


Make it a requirement for the user to check first that the queue is not empty (provide means for that).

Then you can:

  • not check anything and simply invoke undefined behavior (access underlying data as if it was there) - it's the user's fault
  • check and throw exception
  • assert (result is undefined with NDEBUG)

Checking and then invoking undefined behavior (returning an arbitrary value) is the worst thing to do. You get both the runtime overhead of the check and the caller is no wiser, as the result is still undefined.

like image 22
visitor Avatar answered Oct 07 '22 10:10

visitor


You could throw a specified exception and catch it accordingly.

like image 35
Simon Linder Avatar answered Oct 07 '22 10:10

Simon Linder


You could also return a class/struct with some magic conversion that is useful for your special need.

Real-life example: once I had actually to return two pieces of information in the same return value, a value to report if a window message had been completely processed and the value to be returned for it if the processing was already completed. So I packed everything up in a class like this:

//This class is used to carry a return value for a window message and a value that indicates if the
//message has already been completely processed
class MessageReturnValue
{
public:
    LRESULT returnValue;
    bool processed;
    MessageReturnValue()
    {
        processed=false;
        returnValue=FALSE;
    };
    MessageReturnValue(LRESULT ReturnValue)
    {
        processed=true;
        returnValue=ReturnValue;
    };
    MessageReturnValue(bool Processed)
    {
        returnValue=FALSE;
        processed=Processed;
    };
    inline operator bool()
    {
        return processed;
    };
    inline operator LRESULT()
    {
        return returnValue;
    };
};

This allowed me to do just return false; in a function that returned a MessageReturnValue if the message had still to be processed, or to return TRUE/15/whatever; if the message had been completely processed and I already had a return value. The caller, on its side, could simply do

LRESULT MyWndProc(/* blah blah blah */)
{
    MessageReturnValue ret = MyFunction(/* blah blah blah */);
    if(!ret)
    {
        /* process the message */
        return /* something */;
    }
    else
        return (LRESULT)ret;
}

If you have more complicated needs, you could also consider using boost::tuple.

like image 31
Matteo Italia Avatar answered Oct 07 '22 09:10

Matteo Italia