Luchian Grigore
Luchian Grigore

Reputation: 258618

Trigger event on return in C++

I want to execute some function right before the return of another function. The issue is that there are multiple returns and I don't want to copy-paste my call before each of them. Is there a more elegant way of doing this?

void f()
{
    //do something
    if ( blabla )
        return;
    //do something else
    return;
    //bla bla
}

I want to call g() before the function returns.

Upvotes: 4

Views: 2023

Answers (8)

mkaes
mkaes

Reputation: 14119

There are some ways to do this.
One would be to use boost::scope_exit or use a struct and do your work in the destructor.
I dislike the preprocessor syntax of boost and I am too lazy to write struct so I prefer using a boost::shared_ptr or on newer compilers a std::shared_ptr. Like this:

std::shared_ptr<void>(nullptr, [](void*){ /* do your stuff here*/ });

Upvotes: 7

husky76
husky76

Reputation: 31

#define RETURN_IT g(); \
        return;

void f()
{
    //do something
    if ( blabla )
        RETURN_IT;
    //do something else
    RETURN_IT;
    //bla bla
}

Simple, although I do kind of like loki's suggestion

Upvotes: 3

Ragesh Chakkadath
Ragesh Chakkadath

Reputation: 1531

I think try-finally statements will do what you want.

void f()
{
    __try
    {
       //do something
       if ( blabla )
           return;
       //do something else
       return;
      //bla bla
    }
    __finally
   {
      g();
   }
}

The try-finally statement is a Microsoft extension to the C and C++ languages that enables target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The try-finally statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine.

Quoted from msdn.

Upvotes: 4

ravenspoint
ravenspoint

Reputation: 20576

void f()
{
    //do something
    if ( blabla )
        return;
    //do something else
    return;
    //bla bla
}

void f_callg()
{
    f();
    g();
}

If there is no access to where f() is called from

void f_copy_of_old()
{
    //do something
    if ( blabla )
        return;
    //do something else
    return;
    //bla bla
}

void f()
{
f_copy_of_old();
g();
}

Upvotes: 2

Mark B
Mark B

Reputation: 96281

This is often a sign that instead of trying to artificially do something before every return, you should try to refactor your function into single-exit form. Then it's super easy to do your extra step because...there's only one return.

Upvotes: 4

laurent
laurent

Reputation: 90804

For this kind of thing, you could simply use a boolean. That way you don't have too many if/else statements:

void f()
{
    //do something
    done = false;
    if ( blabla )
        done = true;
    //do something else

    if (!done) {
        // some code
        done = true;
    }

    if (!done) {
        // some other code
        done = true;
    }

    return;
}

Upvotes: 2

Lea Hayes
Lea Hayes

Reputation: 64216

int g() {
    // blah
    return 0;
}

void f() {
    // do something
    if (blabla)
        return g();
    // do something else
    return g();
}

Upvotes: 0

Andrey Agibalov
Andrey Agibalov

Reputation: 7694

struct DoSomethingOnReturn {
  ~DoSomethingOnReturn() {
    std::cout << "just before return" << std::endl;
  }
};
...
void func() {
  DoSomethingOnReturn a;
  if(1 > 2) return;      
}

Upvotes: 12

Related Questions