This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/17232] classes and class template specializations treated differently w.r.t. core issue #337
- From: "cludwig at cdc dot informatik dot tu-darmstadt dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 30 Aug 2004 13:22:51 -0000
- Subject: [Bug c++/17232] classes and class template specializations treated differently w.r.t. core issue #337
- References: <20040829175551.17232.cludwig@cdc.informatik.tu-darmstadt.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From cludwig at cdc dot informatik dot tu-darmstadt dot de 2004-08-30 13:22 -------
Subject: Re: classes and class template specializations treated differently w.r.t. core issue #337
On Mon, Aug 30, 2004 at 12:30:28PM -0000, giovannibajo at libero dot it wrote:
> The problem is that A<int> was not instantiated at the point of call. So the
> compiler does not know yet if A<int> is an abstract type or not -- it will have
> to instantiate that to do so. Now, I am not sure we should force an
> instantiation just because we are trying to form an array type and we need to
> check for abstractness, I fear this requires a clarification from
> C++ gurus.
IMHO the class template needs to be instantiated:
14.7.1/p4 (Implicit Instantiation)
A class template specialization is implicitly instantiated if the
class type is used in a context that requires a completely defined
object type or if the completeness of the class type affects the
semantics of the program; in particular, if an expression whose type
is a class template specialization is involved in overload
resolution, pointer conversion, pointer to member conversion, the
class template specialization is implicitly instantiated (3.2);
[...]
In my testcase, the semantics of the program depends on the
completeness of A<int> and the class template specialization is
obviously involved in overload resolution. I therefore think an
implicit specialization is warranted.
> The simple workaround is to force an instantiation of the class to happen
> before the call. I don't know if it is possible in your application, though.
> For the testcase, you need to add a "template struct A<int>;" somewhere before
> the call.
Unfortunately, explicit instantiation is not a viable alternative in
my project. But I have another workaround, see below.
> What EDG does is to simply ignore the abstract constraint in this situation,
> and allow the call. It will then error out when the array is first used in the
> body of the function as the underlying type is abstract -- but it seems to me
> as a violation of [dcl.array]/1 which says that it is invalid to (just) declare
> an array to abstract type.
Do I understand you correctly, EDG based compilers will call the first
overload for A<int>? Since my testcase never actually uses the array,
there won't be any error and the function call g< A<int> >(0) will
return 0? (I don't have access to an EDG based compiler whence I
cannot easily test it myself.)
> I think you are better off raising this issue with comp.std.c++, and get back
> to us. If there is agreement that EDG is wrong and the template deduction
> should be rejected through an instantiation of the argument, I can implement
> this solution into the compiler (I implemented DR 337 in the first place).
Sure, I will post this problem to comp.std.c++.
> I also would like to know if this affects your application in a way that causes
> a regression (that is, 3.3 works but 3.4 does not), because your testcase is
> wisely constructed as a regression, but the actual bug is not (since DR 337 was
> first implemented in 3.4, and has this "bug" since then).
I don't think you can call it a regression.
I am using the new Boost serialization library that needs to handle
abstract classes differently. For gcc >= 3.4 it uses the
boost::is_abstract type trait to recognize abstract base classes and
it is therefore affected by this problem if the abstract base class is
in fact a template specialization.
For gcc <= 3.3.x it is known that DR 337 is not implemented whence
boost::is_abstract fails. The user must explicitly mark abstract
classes (essentially by an explicit specialization of
boost::is_abstract) if the serialization library is used with
gcc <= 3.3.x.
Regards
Christoph
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17232