Bug Report: destructor of temporary not called.

  • Thread starter Jonathan Turkanis
  • Start date
J

Jonathan Turkanis

Dear All,

I'm using VC7.1.

The test program at the end of this message initializes a member
variable of reference type with a temporary. I believe the program
should output

counter = 0;
counter = 0;

indicating that the total number of objects of the temporary's type is
0 at the beginning and the end of main().

Instead, I get the output

counter = 0;
counter = 1;

indicating that the destructor of (at least one copy of) the temporary
is never called.

This program produces the expected output when compiled using Intel
8.0 for Windows, Comeau 4.3.3, GCC 3.2 (MinGW), Codewarrior 8.3 and
Borland 5.6.4.

Is this a bug, or is my program illegal for some reason? If it is a
bug, are there any known workarounds?

Best Regard,
Jonathan Turkanis

//--------Test program -------------------------//

#include <iostream>

int counter;

struct ref {
ref () { ++counter; }
ref (const ref &) { ++counter; }
~ref () { --counter; }
};

struct test {
test() : r(ref()) { }
const ref & r;
};

int main()
{
std::cout << "counter = " << counter << "\n";
{
test t;
}
std::cout << "counter = " << counter << "\n";
}
 
S

Stu Smith

Jonathan Turkanis said:
Dear All,

I'm using VC7.1.

The test program at the end of this message initializes a member
variable of reference type with a temporary. I believe the program
should output

counter = 0;
counter = 0;

indicating that the total number of objects of the temporary's type is
0 at the beginning and the end of main().

Instead, I get the output

counter = 0;
counter = 1;

indicating that the destructor of (at least one copy of) the temporary
is never called.

This program produces the expected output when compiled using Intel
8.0 for Windows, Comeau 4.3.3, GCC 3.2 (MinGW), Codewarrior 8.3 and
Borland 5.6.4.

Is this a bug, or is my program illegal for some reason? If it is a
bug, are there any known workarounds?

I think it's a bug but then I'm not an expert. I thought the lifetime of the
temporary in this case was supposed to be the lifetime of the reference,
which in this case is the lifetime of t.

Workaround.... store the ref directly within test, instead of a reference.
Also why does you copy-ctor increment the count? I'm not sure that's
correct.

Stu
 
D

David Lowndes

The test program at the end of this message initializes a member
variable of reference type with a temporary. I believe the program
should output

counter = 0;
counter = 0;

You'd intuitively think that - but it'll take a language lawyer to
know for sure. It feels as though it's an ambiguous aspect to me. I
can envisage cases for both behaviours.

You could add an explicit destruction:

~test()
{
r.~ref();
}
This program produces the expected output when compiled using Intel
8.0 for Windows, Comeau 4.3.3, GCC 3.2 (MinGW), Codewarrior 8.3 and
Borland 5.6.4.

I'll try to pass it on to MS since it produces the same results with
the VS2005 beta compiler.

Dave
 
J

Jonathan Turkanis

Stu Smith said:
I think it's a bug but then I'm not an expert. I thought the lifetime of the
temporary in this case was supposed to be the lifetime of the reference,
which in this case is the lifetime of t.

I think this falls within the first exception of 12.2/5, relating to
ctor-initlizers, so that the temporary should be destroyed when the
constructor exits. Anyway, this is what I was trying to test
Workaround.... store the ref directly within test, instead of a
reference.

This won't do what I want, unfortunately.
Also why does you copy-ctor increment the count? I'm not sure that's
correct.

I want to count the total number of object creations, including
copies.

Thanks,

Jonathan
 
J

Jonathan Turkanis

You'd intuitively think that - but it'll take a language lawyer to
know for sure. It feels as though it's an ambiguous aspect to me. I
can envisage cases for both behaviours.

You could add an explicit destruction:

~test()
{
r.~ref();
}

Unfortunately, what I was hoping I could do is get the destructor of a
derived class called without a virtual desructor, ala ScopeGuard. But
I think this case falls under the first exception in 12.2/5. This is
how the other compilers behave, anyway.
 
S

Stu Smith

Jonathan Turkanis said:
I think this falls within the first exception of 12.2/5, relating to
ctor-initlizers, so that the temporary should be destroyed when the
constructor exits. Anyway, this is what I was trying to test

Yep I saw that too but I wasn't sure if this was the same case.
reference.

This won't do what I want, unfortunately.


I want to count the total number of object creations, including
copies.

Do you mean the total number of creations of test? Because the ref copy-ctor
won't be called for that surely? Shouldn't the copy-ctor be on test? And
then I'd make the copy and assign methods on ref private to be sure.

And if I've said something stupid, sorry, I've been using C# for the past
two years.
 
J

Jonathan Turkanis

Stu Smith said:
Do you mean the total number of creations of test? Because the ref copy-ctor
won't be called for that surely? Shouldn't the copy-ctor be on test? And
then I'd make the copy and assign methods on ref private to be sure.

I wanted to count the number of refs, since I wanted to see if the
temporary created by ref() is being destroyed.
And if I've said something stupid, sorry, I've been using C# for the past
two years.

That should make you smarter. ;-)

Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top