16

I searched for the answer to this question and wasn't able to find one. Consider the following code:

struct Foo
{
    int *bar;
    Foo(int barValue) : bar(new int(barValue)) {}
    ~Foo() { do_this(); }
    void do_this() { delete bar; bar = nullptr; }
};

int main()
{
    const Foo foo(7);
}

do_this() cannot be called on a const object, so I couldn't do something like foo.do_this(). It would also make sense in some situations to call do_this() outside of the destructor, which is why I don't want to simply include the code in the destructor definition. Because do_this() modifies a member variable, I can't declare it as const.

My question is: will the destructor be able to call do_this() on a const object when the object is destroyed?

I tried it and received no errors, but I want to make sure I'm not causing a memory leak once my program terminates.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
Mike Borkland
  • 714
  • 1
  • 5
  • 12
  • 1
    [Somewhat related](https://stackoverflow.com/a/8372475/7359094). – François Andrieux Mar 06 '18 at 16:40
  • You pretty much *have* to be able to modify the object in the destructor in order to free up resources. Whether that happens directly in the destructor or in some other function doesn't matter. – Kevin Mar 06 '18 at 16:43
  • 3
    "... causing a memory leak once my program terminates..." Makes no sense. Once the program *terminates* all resources it allocated are freed by the kernel - leaks are no longer a concern. Leaks *are* a concern when they happen while the program is running, since you may then run out of resources. But after termination, worrying about leaks is void. – Jesper Juhl Mar 06 '18 at 16:53
  • but mutating `const` object is UB... – Jarod42 Mar 06 '18 at 16:53
  • @Jarod42: While it is `const`, yes. That's a rather relevant limitation. It's also why the constructor and destructor are `special functions`. – MSalters Mar 06 '18 at 16:55
  • @Jesper Juhl True, thanks. – Mike Borkland Mar 06 '18 at 16:59
  • @JesperJuhl this is strictly true, but with SBRM (or RAI) we should not care about memory leak that much as we care about unfreed resources in general. And some of those can certainly outlive the application. Because of that, I think the question is valid, even is in a broader scope. – SergeyA Mar 06 '18 at 17:00
  • @SergeyA Sure, for *non*-memory resources, running destructors may be important. But, the question *specifically* said "memory leaks". – Jesper Juhl Mar 06 '18 at 17:04
  • @JesperJuhl I know. I just believe that by slightly expanding the definition we can get some benefits :) Also, in the nitpicking mode, nothing in the question actually tells us that OP is using a kernel, may be it is an embedded device where memory is not managed by outside entity? – SergeyA Mar 06 '18 at 17:19

1 Answers1

17

Yes, you can certainly and safely call non-const functions from destructor. Standard explicitly allows this:

15.4/2 A destructor is used to destroy objects of its class type. The address of a destructor shall not be taken. A destructor can be invoked for a const, volatile or const volatile object. const and volatile semantics ([dcl.type.cv]) are not applied on an object under destruction. They stop being in effect when the destructor for the most derived object starts.

SergeyA
  • 61,605
  • 5
  • 78
  • 137