Is explicit template qualification required for explicit delete?

J

J.T. Conklin

I've been working on the configuration infrastructure for the ACE
framework which contains code that uses a templatized handle/body
idiom with placement new/delete. With g++ 3.4, we found that the
delete needed the addition of a template argument that wasn't needed
in earlier versions. I've checked this with Comeau C++ Online in
strict mode, and with Gimpel's Flexelint and neither reported any
issues with the code without the template argument. I realize that
whether a given compiler accepts/rejects a bit of code doesn't mean
anything, so I've checked C++PLv3 and the C++ standard, but haven't
been able to tell whether g++ is being strict, or is in error.

Here is some sample code that demonstrates the issue:

#include <cstdlib>
#include <new>

template <class T>
class Body
{
public:
Body () { }
~Body () { }
};

template <class T>
class Handle
{
public:
Handle ()
{
void *ptr = std::malloc(sizeof(Body<T>));
x_ = new (ptr) Body<T> ();
}

virtual ~Handle ()
{
#ifdef WITH_TEMPLATE_ARG
x_->~Body <T> ();
#else
x_->~Body ();
#endif
std::free(x_);
}

private:
Body<T> *x_;
};


int
main()
{
Handle<int> *x = new Handle<int> ();
delete x;

return 0;
}

Everything I've tried compiles this code with WITH_TEMPLATE_ARG defined,
but so far only g++ 3.4 rejects it without.

Many thanks,

--jtc
 
D

David Hilsee

J.T. Conklin said:
I've been working on the configuration infrastructure for the ACE
framework which contains code that uses a templatized handle/body
idiom with placement new/delete. With g++ 3.4, we found that the
delete needed the addition of a template argument that wasn't needed
in earlier versions. I've checked this with Comeau C++ Online in
strict mode, and with Gimpel's Flexelint and neither reported any
issues with the code without the template argument. I realize that
whether a given compiler accepts/rejects a bit of code doesn't mean
anything, so I've checked C++PLv3 and the C++ standard, but haven't
been able to tell whether g++ is being strict, or is in error.

Here is some sample code that demonstrates the issue:

#include <cstdlib>
#include <new>

template <class T>
class Body
{
public:
Body () { }
~Body () { }
};

template <class T>
class Handle
{
public:
Handle ()
{
void *ptr = std::malloc(sizeof(Body<T>));
x_ = new (ptr) Body<T> ();
}

virtual ~Handle ()
{
#ifdef WITH_TEMPLATE_ARG
x_->~Body <T> ();
#else
x_->~Body ();
#endif
std::free(x_);
}

private:
Body<T> *x_;
};


int
main()
{
Handle<int> *x = new Handle<int> ();
delete x;

return 0;
}

Everything I've tried compiles this code with WITH_TEMPLATE_ARG defined,
but so far only g++ 3.4 rejects it without.

Well, my copy of the standard says that a destructor call is ~class-name,
and a template-id (template name with arguments, e.g. Handle<int>) qualifies
as a class-name, so the universal acceptance of ~Body<T>() makes sense to
me. The other option for class-name is identifier, which doesn't help me
much. It is true that Handle is an identifier, but that doesn't necessarily
mean that it can be used to invoke the destructor, right? I'm probably
missing something. You might want to also post this to
comp.lang.c++.moderated, if you haven't already.
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top