Issue 3516 - Destructor not called on temporaries
Summary: Destructor not called on temporaries
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Windows
: P3 critical
Assignee: No Owner
URL:
Keywords: wrong-code
: 3285 3518 4613 (view as issue list)
Depends on:
Blocks: 4490
  Show dependency treegraph
 
Reported: 2009-11-16 14:32 UTC by Bartosz Milewski
Modified: 2015-06-09 01:26 UTC (History)
12 users (show)

See Also:


Attachments
Reference counting doesn't work when temporaries created (1.75 KB, application/octet-stream)
2009-11-16 14:32 UTC, Bartosz Milewski
Details

Note You need to log in before you can comment on or make changes to this issue.
Description Bartosz Milewski 2009-11-16 14:32:39 UTC
Created attachment 497 [details]
Reference counting doesn't work when temporaries created

Function f returns (by value) a struct that has a destructor. If I explicitly
assign the result of f to a temporary, that temporary is destroyed at the end
of scope. If I don't assign it, the hidden temporary is not destroyed. In the
attached example this screws up reference counting.
Comment 1 Bartosz Milewski 2009-11-16 16:31:43 UTC
*** Issue 3518 has been marked as a duplicate of this issue. ***
Comment 2 Leandro Motta Barros 2009-11-29 03:21:36 UTC
I don't know if this is useful information, but I've been bitten by this same bug under Linux with DMD 2.036.
Comment 3 Brad Roberts 2010-05-30 15:59:09 UTC
Reduced test case:
extern(C) int printf(const char*, ...);

int numctor, numdtor;

struct Tid
{
    this(int i) { ++numctor; }
    ~this() { ++numdtor; }
}

Tid f() { return Tid(1); }

// This temporary is destroyed
void test1() { Tid tid = f(); }

// This (invisible) temporary is never destroyed
void test2() { f(); }

void main()
{
    numctor = numdtor = 0;
    test1();
    printf("numctor = %d, numdtor = %d\n", numctor, numdtor);
    assert(numctor == 1);
    assert(numdtor == 1);

    numctor = numdtor = 0;
    test2();
    printf("numctor = %d, numdtor = %d\n", numctor, numdtor);
    assert(numctor == 1);
    assert(numdtor == 1);
}

Current results:
numctor = 1, numdtor = 1
numctor = 1, numdtor = 0
core.exception.AssertError@bug3516(31): Assertion failure
Comment 4 Lionello Lunesu 2010-07-06 01:34:59 UTC
*** Issue 3285 has been marked as a duplicate of this issue. ***
Comment 5 Adrian Matoga 2010-07-10 06:11:10 UTC
Still active in 2.047,

testcase:

import std.stdio;
struct A
{
	int a;
	this(int a) { this.a = a; writeln("hello, ", a); }
	~this() { writeln("bye, ", a); }
	void doSth() { writeln("something"); }
}
void main()
{
	auto a1 = A(1);
	a1.doSth();
	A(2).doSth();
}

produces:

hello, 1
something
hello, 2
something
bye, 1
Comment 6 Andrei Alexandrescu 2010-07-10 06:25:14 UTC
Upvoted.
Comment 7 SHOO 2010-08-23 09:52:25 UTC
Upvoted.
By recent usage of struct, this bug is serious. This should be supported quickly.

I suspect that these may be connected with each other:
    http://d.puremagic.com/issues/show_bug.cgi?id=4712
Comment 8 andy 2010-09-20 08:51:34 UTC
This bug also seems like it could be the cause of

http://d.puremagic.com/issues/show_bug.cgi?id=4613
Comment 9 Don 2010-09-22 04:05:41 UTC
*** Issue 4613 has been marked as a duplicate of this issue. ***
Comment 10 Max Samukha 2010-11-14 03:09:58 UTC
This one is critical for QtD. Can it be fixed soon?
Comment 11 Vladimir Panteleev 2011-04-26 05:19:34 UTC
The test case in comment #3 now passes with DMD git HEAD, and this bug is now listed as fixed in the DMD changelog.
Comment 12 Don 2011-06-27 03:06:44 UTC
Closing this bug, as all of the test cases in this report now work, and destructors are also called when exceptions are present:

https://github.com/D-Programming-Language/dmd/commit/41abb2b915d1c826af83a2c8cba5f6fb646d1089

If there are any remaining cases where destructors are not called, they should be reported as a different bug.