4

I wrote this code as follows:

#include <iostream>

using namespace std;

class T
{
    public:
    T()
    {
        cout << "bb\n";
        this -> ~T();
        cout << "zz" << endl;
    }
    ~T()
    {
        cout << "hello\n";
    };
};



int main()
{
    T a;
    return 0;
}

Edited

Sorry, it should be T a; instead of T a(),and now I get the output:

bb
hello
zz
hello

But I'm confused about the result.Why this program can run successfully?

Edited

I don't think my question is duplicate. In my code, the constructor calls the destructor before the function is finished. However, it called twice destructor explicitly in that question.

mrsiz
  • 193
  • 9
  • 1
    Most vexing parse. If you fix that, most certainly UB. – Baum mit Augen Nov 15 '16 at 11:13
  • `T a();` -- This doesn't call a function. Also in general, you can write any sort of nonsense in C++ that may compile without error. So my advice is to not waste too much time trying to figure out nonsense code. – PaulMcKenzie Nov 15 '16 at 11:14
  • If nothing else, undefined behaviour will be caused when `a` goes out of scope, and the destructor invoked for an object that was already destroyed – M.M Nov 15 '16 at 11:29
  • Possible duplicate of [Does explicitly calling destructor result in Undefined Behavior here?](http://stackoverflow.com/questions/3291507/does-explicitly-calling-destructor-result-in-undefined-behavior-here) – fredrik Nov 15 '16 at 11:30
  • ^ not a duplicate, in that case the destructor is called after the constructor has completed, which is a significant difference – M.M Nov 15 '16 at 11:31
  • He's stil explicitly calling the destructor - and that is undefined behaviour. Doesn't matter where it's being called from now does it? – fredrik Nov 15 '16 at 11:31
  • @fredrik explicitly calling the destructor is not undefined behaviour – M.M Nov 15 '16 at 11:31
  • @M.M It will result in undefined behavious - as the program will call the destructor again when the object is destroyed, and calling a destructor twice is undefined behaviour per the parts of the specification qouted in the question referenced. Even if calling the destructor is not undefined in itself - the end result is. – fredrik Nov 15 '16 at 11:34
  • 1
    @fredrik see the variation in Hrishikesh Goyal's answer, in which the object is not destroyed again later . The question remains whether calling the destructor in the constructor is undefined behaviour or not – M.M Nov 15 '16 at 11:36
  • @M.M That's only because he's not deallocating the object - I would say that a memory leak is just as bad and I rest my case. – fredrik Nov 15 '16 at 11:38
  • Memory leaks are not undefined behaviour. – M.M Nov 15 '16 at 11:39
  • Memory leak is avoidable as well (e.g. with placement new and explicit deallocation) and in any case they are completely different issues. – SomeWittyUsername Nov 15 '16 at 11:47
  • Herb Sutter talks about the validity of destructor calls in different scopes, seems to imply that it's indeed UB - https://herbsutter.com/2008/07/25/constructor-exceptions-in-c-c-and-java/ – SomeWittyUsername Nov 15 '16 at 12:06

2 Answers2

4

This is undefined behaviour: you're calling the destructor on an object which has not yet been fully constructed.

Smeeheey
  • 9,906
  • 23
  • 39
  • Where's it specified it's UF? – nbro Nov 15 '16 at 11:16
  • @StoryTeller explain the relevance of that quote to the issue of calling the destructor from the constructor? – M.M Nov 15 '16 at 13:03
  • @M.M Is that a question or a demand!? Having a constructor called more than once is UB. Circumstances are irrelevant. The answer above may be wrong no the why, but not on the fact itself. – StoryTeller - Unslander Monica Nov 15 '16 at 13:15
  • There's 2 separate issues here, (a) calling the destructor in the constructor, (b) calling the destructor twice. Based on the title I think OP wants to know about (a) . This answer claims (a) is undefined with no evidence, and your quote is only relevant to (b). – M.M Nov 15 '16 at 13:16
  • @M.M Yes, you can twiddle around with placement new and argue that the OPs example would be fine according to [[basic.life/6](http://eel.is/c++draft/basic.life#6)]. But the OP asked about a variable with automatic storage. And in that case it *is* UB. – StoryTeller - Unslander Monica Nov 15 '16 at 13:23
-2

When you call a destructor inside a constructor and you don't delete the dynamically generated memory explicitly using delete statement then it gonna work just like a normal function call. For the reference I have made the appropriate changes in the code so that destructor behaves normal.

#include <iostream>
using namespace std;

class T
{public:
    T()
    {
        cout << "bb\n";
        this -> ~T();
        cout << "zz" << endl;
    }
    ~T(){cout << "hello\n";};
};


int main()
{
    T* a= new T();
    return 0;
}

output :

bb
hello
zz
hrishi
  • 443
  • 2
  • 12
  • 4
    @bolov you're going to have to justify that with standard quotes – M.M Nov 15 '16 at 11:33
  • I can't find anything in the C++14 standard that makes this code UB – M.M Nov 15 '16 at 11:59
  • The first paragraph of this answer needs some fixing though, it's not exactly like a norma function call because you certainly cannot access any non-static members of the class (or even evaluate the pointer `a`) after the destructor call – M.M Nov 15 '16 at 12:05
  • @M.M when I'll have some free time I'll take a look into the standard. – bolov Nov 15 '16 at 12:24