-1

I have the following function:

Class Image {

    IplImage* createImage( char* name )
    {
        IplImage* img = cvLoadImage( name );

        return img;

        ...
    }
}

int main() {
    IplImage* newimg = createImage( "somepath" );
    return 0;
}

After the createImage function is been executed I would like to know if there's a way to execute some code after the return statement has been accessed and the newimg has been populated with the contents of the img variable.

The above code is an example of what I want to achieve. My main question is: Is there any way I can execute code in a function even after the return statement has been reached?

karlphillip
  • 92,053
  • 36
  • 243
  • 426
Nicolas Epaminonda
  • 181
  • 1
  • 3
  • 13
  • 2
    Erm.. why don't you just put the `return` at the end? I mean, it's pretty clear that control *leaves* the function when it reaches a return statement... – Xeo Jan 06 '12 at 19:18
  • Aside from `goto`, no. Why would you want to do this? Break the logic out into multiple functions, that is the correct approach. – Chad Jan 06 '12 at 19:18
  • 3
    What is your goal in trying to do this? Even if this were possible, that is highly counter-intuitive, and there is likely a Better Way. – Nate Jan 06 '12 at 19:18

6 Answers6

6

NO! The return instruction does exactly that, it returns immediately. Whatever is after it won't be executed.

So if there's anything else you would like this function to do, you must add the code for these tasks before the function return:

IplImage* createImage( char* name )
{
    IplImage* img = cvLoadImage( name );

    // test if image was loaded and/or
    // do whatever else you feel you need to do
    // before:

    return img;
}

Remember, your function createImage() should be simple and perform as advertised: create an image.

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • it looks simple, but even after the return statement has been reached and the function ceases to exist, the **img** is a pointer and would still be in memory (which I am not quite sure if that's correct, but I am guessing that would create a memory leak) – Nicolas Epaminonda Jan 06 '12 at 19:43
  • 1
    @Nicolas Ah, I see where this is going, this question is specific to OpenCV. Ok, here we go: `cvLoadImage()` loads the image in the HEAP memory not in the stack. That's why there's still memory allocated after the function returns. The only way to free the resources this function has allocated is through `cvReleaseImage()`. This is normal behavior. Let it go. – karlphillip Jan 06 '12 at 22:42
4

Yes, you can create a local object which will execute code during its destructor. Here is an example:

class X
{
    X(){}

    ~X()
    {
        std::cout << "hello" << std::endl;
    }
};

int a_function()
{
    X x;

    int a = some_calculation();
    return a;
}

This technique is for example used with scope pointers.

neodelphi
  • 2,706
  • 1
  • 15
  • 22
  • 1
    And remember that the constructor for the object can take a reference to a local variable if there is a need to act on it - as long as it isn't also destroyed at the return. – Mark Ransom Jan 06 '12 at 22:55
2

To answer the question, no it is not possible to execute code after newimg has been initialized (atleast not in the createImage function). This is the closest you can get:

struct post_return_guard{
  ~post_return_guard(){
     // whatever you want HERE
  }
};

IplImage* createImage(std::string const& name){
  post_return_guard g;
  IplImage* img = cvLoadImage(name.c_str());
  return img;
  // destructor of 'g' called, code executed.
}
Xeo
  • 129,499
  • 52
  • 291
  • 397
  • +1. Technically this doesn't correctly answer the question (which stipulates that the code be executed "after [...] the newimg has been populated with the contents of the img variable"), but it's as close as you can get. – ruakh Jan 06 '12 at 19:24
  • that is a really nice way of thinking. but what if, let's say, I want to release the **img** pointer? Would I still be able to do it in g's destructor? – Nicolas Epaminonda Jan 06 '12 at 19:34
1

Every bit auf code after a (unconditional) return statement of any function/method in C/C++ is unreachable code and will never be accessed/run!

Mithrandir
  • 24,869
  • 6
  • 50
  • 66
  • `int main() { if(0) { return 1; } printf("Reachable code.\n"); return 0; }` might disagree. The phrase "**the** return statement of any function/method in C/C++" is inherently misleading. – ruakh Jan 06 '12 at 19:22
1

This is what you should be doing.

Class Image {

    IplImage* createImage( char* name )
    {
        IplImage* img = cvLoadImage( name );
        return img;
    }
}
void doMoreStuff(){
        ...
}
int main() {
    IplImage* newimg = createImage( "somepath" );
    doMoreStuff();
    return 0;
}
Isaac Fife
  • 1,659
  • 13
  • 15
  • yes, this is not exactly what I am asking for. what I am asking for is whether I can have any code within the **createImage** function that can be executed even after the return statement has been achieved, and be able to have access to the variables created within that function. – Nicolas Epaminonda Jan 06 '12 at 19:38
0

It's not difficult; just return a proxy object (rather than a pointer) which executes code in its destructor. Since you're expecting a pointer in return, the proxy object should also convert implicitly to a pointer.

Having said that, however: why would you? What are you trying to do which can't be done in createImage, between the moment you call cvLoadImage and the moment you return?

James Kanze
  • 150,581
  • 18
  • 184
  • 329