Spurious destructor call, or ill-formed code?
Sam Varshavchik
mrsam@courier-mta.com
Mon Aug 27 00:29:00 GMT 2012
I ran into this while porting some code from Linux to FreeBSD, and I
isolated this to a small example. The example uses a class that dumps a
diagnostic in its constructor and destructor, and juggles a couple of
instances of the class, using a couple of lambdas.
"g++47 (FreeBSD Ports Collection) 4.7.0 20111203 (experimental)" invokes the
destructor of two instances of this class twice. Sample output (highlighting
what I've now wasted a week on):
$ /tmp/t
Constructed 0x7fffffffdb00: 24
other: 24: 0x7fffffffdb00
Copied 0x7fffffffdb00 to 0x7fffffffdb20
Constructed 0x7fffffffdb30: 42
orig: 42: 0x7fffffffdb30
Copied 0x7fffffffdb30 to 0x7fffffffda90
cpy: 42: 0x7fffffffda90
Copied 0x7fffffffdb20 to 0x7fffffffda80
Copied 0x7fffffffda90 to 0x7fffffffdac0
Copied 0x7fffffffda80 to 0x7fffffffdac4
lambda: 42: 0x7fffffffdac0
other_lambda: 24: 0x7fffffffdac4
Destroyed 0x7fffffffdac0 ******
Destroyed 0x7fffffffdac4 ******
Destroyed 0x7fffffffdac4 ******
Destroyed 0x7fffffffdac0 ******
Destroyed 0x7fffffffda80
Destroyed 0x7fffffffda90
Destroyed 0x7fffffffdb30
Destroyed 0x7fffffffdb20
Destroyed 0x7fffffffdb00
With "g++ (GCC) 4.7.0 20120507 (Red Hat 4.7.0-5)" the extra destructor calls
do not occur. The output is the same, except for two of the destructor calls
(ignoring the differences in the pointer values).
In both cases, I'm using only -std=c++0x to compile the following. As far as
I can tell, I'm capturing everything by value, and I can't see what's ill-
formed here:
#include <iostream>
#include <string>
#include <type_traits>
class sw {
public:
int s;
sw(const int &sa) : s(sa)
{
std::cout << "Constructed " << this << ": " << s << std::endl;
}
~sw()
{
std::cout << "Destroyed " << this << std::endl;
}
sw(const sw &o) : s(o.s)
{
std::cout << "Copied " << &o << " to " << this << std::endl;
}
sw &operator=(const sw &o)
{
s=o.s;
std::cout << "Assigned " << &o << " to " << this << std::endl;
return *this;
}
void identify(const std::string &str) const
{
std::cout << str << ": " << s << ": " << this << std::endl;
}
};
template<typename lambda2>
void foo(sw &&orig, lambda2 &&lambda)
{
orig.identify("orig");
sw cpy(orig);
cpy.identify("cpy");
lambda2 lambda_cpy(std::move(lambda));
[cpy, lambda_cpy]
{
cpy.identify("lambda");
lambda_cpy();
}();
}
int main(int argc, char **argv)
{
sw other(24);
other.identify("other");
foo(sw(42),
[other]
{
other.identify("other_lambda");
});
return (0);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-help/attachments/20120827/ee483c18/attachment.sig>
More information about the Gcc-help
mailing list