3
int foo() {
    Magic magic;

    if (something) return 1;
    if (something_else) return 2;

    return 0;
}

Let's say that I have a function such as the above;

  • is it possible for magic destructor to refer to the value the function is about to return?

class Magic {
    ~Magic() {
        int return_code = <magic spell>;
        std::cout << "the method returns" << return_code;
    }
};

-- EDIT --

For example, golang has named return variables that you can access and/or modify from a defer statement - after they are "returned" from the body of the function.

gsf
  • 6,612
  • 7
  • 35
  • 64
  • Why does your destructor need to know this information in order to clean up the state of Magic? – Neil Kirk Feb 19 '15 at 00:16
  • In C++ there is no concept of Finally, because there is RAII. RAII is very powerful and exceeds in many cases its use to cleaning the object. There are already patterns that demonstrate http://stackoverflow.com/questions/161177/does-c-support-finally-blocks-and-whats-this-raii-i-keep-hearing-about such usage. It is limited though to local variables. I hope there could be a seamless way without need of a helper local variable the return code to be obtained at system level. – gsf Feb 19 '15 at 00:28
  • Destructors are not time machines. They do not have access to return values from functions that have not yet returned in code that has not yet executed. – jalf Feb 19 '15 at 00:28
  • Can you call a function on magic to pass it the variable and store it as a member? Some compilers support finally as an extension. – Neil Kirk Feb 19 '15 at 00:32
  • It was a long shot anyways, I will probably need to hide some local variable behind a macro or something. – gsf Feb 19 '15 at 00:35
  • I think you should figure out what's wrong with your design. – Neil Kirk Feb 19 '15 at 00:35
  • Wow, you are sure of it, hah. – gsf Feb 19 '15 at 00:38
  • Could you go a little into why you want to do this, and more importantly, why you think it is a good idea to do this? I have a sneaking suspicion that what you want to do is totally valid, but your implementation of the idea using "return values" is likely overlooking an easier implementation that we could help you find. You say "RAII is limited to local variables," and you want a "system level" solution. It might help to better understand what you mean by that. Take a look at marcus' answer, I've got a hunch its what you want, even though its not exactly what you're asking for. – Cort Ammon Feb 19 '15 at 00:50
  • Yes, his answer is the classic RAII usage for providing finally in a particular scope with accessing local variable. In my case if we limit the scope to a whole function, I wish there was an easy way the about to return value to be accessible, say it is a success/error code that I would like to check to determine the final logic. – gsf Feb 19 '15 at 00:52
  • Usually this is done, with helper method, do { ... } while (0); or goto. I was just hoping that I could find a better way to do it. – gsf Feb 19 '15 at 00:55
  • I must admit my ignorance. I've never seen any language mechanic which makes the return value "accessable" in this way in any language, except for perhaps LISP's interactive debugger. Are there any examples of what you are trying to do in a language you're trying to emulate? – Cort Ammon Feb 19 '15 at 01:05
  • Other languages offer different instruments. And I cannot use exception, because my code base is mix c/c++. This is why I am stuck with using error codes ... but I hate the int err = 0; do { if (something_wrong) { err = 1; break; } while (0); // finally return err; } pattern because it is too chatty. I am just brainstorming possibilities for the c++ part to do something better. – gsf Feb 19 '15 at 01:08
  • Can you explain the different instruments used by different languages? What you describe is a perfect example of RAII, so I think you're looking for a *very* specific thing in a language you've used elsewhere. I'm a C++ person myself, so I think in C++ terms. I haven't seen anything in your question which isn't naturally handled by RAII, which tells me that I'm failing to see something that you're seeing. If I could see an example in its native language, I may be able to better suggest which C++ features to use to emulate it. – Cort Ammon Feb 19 '15 at 01:19
  • The other instruments I am referring to is the finally in java, and in general the exception handling, that obviously is available in c++, but for string of reasons, not for me. – gsf Feb 19 '15 at 02:15
  • Are you referring to the ability to access local variables in java finally, or are you referring to this: http://stackoverflow.com/questions/8864230/javas-return-value-in-try-catch-finally-mechanism . And you say exceptions are not available to you? That is a substantial detail not in the question: if you are seeking to emulate Java exception-handling without using C++ exception handling, you should not be surprised when you need substantially ugly boilerplate. – Cort Ammon Feb 19 '15 at 02:50
  • Also, do you have C++11? There are many new features which may be helpful for working around the limitations you have to deal with. – Cort Ammon Feb 19 '15 at 02:53
  • I am not surprised. I just believe what Edison said: "there is always a better way" ... and I keep looking for it. You will be suppressed (or maybe not) how innovative a big group like stack overflow community could be. Of course most of the time such questions are downvoted - a lot of people do not make difference between bad question and question without answer, but in some cases there is solution – gsf Feb 20 '15 at 15:05
  • my fevarite example of such question with an answer: http://stackoverflow.com/questions/19760221/c-get-the-month-as-number-at-compile-time – gsf Feb 20 '15 at 15:09
  • @CortAmmon I recently start using go. Interesting enough such capability is very well served in go - and not at all considered odd or anything. In go you can name your return variables- then you can access and even modify them from the lambda code in the defer statement (which is the equivalent of RAII destructor in c++). see this, for example, https://groups.google.com/forum/#!topic/golang-nuts/qTTBENO_Em0 – gsf Sep 17 '16 at 16:12

5 Answers5

1

am not sure if I got the point but maybe this will help you...

#include <iostream>


class Magic {

    const int& _retVal;

public:
    Magic(const int& retVal) : _retVal(retVal)  {}

    ~Magic() {
        std::cout << "foo() returns " << _retVal << std::endl;
    }

};


int foo() {

    int fooRetVal=0;
    Magic magic(fooRetVal);

    if(true)    fooRetVal=1;
    else        fooRetVal=-1;


    return fooRetVal;
}
Cort Ammon
  • 10,221
  • 31
  • 45
marcus
  • 138
  • 1
  • 1
  • 8
  • I modified your code to store a `const int&` instead of an `int`. That lets you construct `Magic` more near the top of the function, which is more similar to the OP's example. – Cort Ammon Feb 19 '15 at 00:44
  • Sure sure...thanks. Am new to this, so sorry for the wrong code flags and thanks for the change, too. – marcus Feb 19 '15 at 00:51
0

I am pretty sure there is no way you can get a destructor to return a value. Destructors don't do that;) It is also not possible to set the return type of the destructor. In your example the destructor will be called after return 0; At that point you cannot get anything at all. You can set up a destructor to modify data by a pointer stored in the Magic class though.

Camleon
  • 113
  • 9
0

No.

A destructor can not return a value, nor should it throw exceptions.

Tobias Schlegel
  • 3,970
  • 18
  • 22
  • Not the destructor to return a value - the destructor to access the value that the function is about to return – gsf Feb 18 '15 at 23:53
  • In your code "magic" is destructed after "return 0;" at the end of the scope. So accessing it beforehand would be too early anyway. I think you want to move code out of the destructor into a member-function. – Tobias Schlegel Feb 18 '15 at 23:56
  • This is the exact order if I would like the return value to be set before I find out what it is. – gsf Feb 18 '15 at 23:59
0

I see. In that case you can conveniently find another elegant solution that does not require using the destructor. The destructor is supposed to free memory and clean up stuff. What you can do (if you really insist) is deleting the object from the heap before return 0 is called...

Camleon
  • 113
  • 9
  • This is the main, but not the only use of destructors, they are very often used as guards, for example boost uses the destructor of scope_lock to unlock the mutex. – gsf Feb 19 '15 at 00:12
  • Ok. I don't understand what you want to achieve with this:). Modify the return value after foo is finished? strange – Camleon Feb 19 '15 at 00:21
0

Yes; the above code simply performs a cout statement in a destructor, i.e. another function. You would have to call the destructor before the return statement since the constructor remains in-scope after return 0.Recall the constructor (and destructor) is just a function returning nothing.

Don Larynx
  • 685
  • 5
  • 15