This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Templates with incomplete types
- From: llewelly at xmission dot com
- To: Matt Austern <austern at apple dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: 09 Jul 2004 12:14:50 -0600
- Subject: Re: Templates with incomplete types
- References: <0C515E34-D10D-11D8-B250-000A95AA5E5E@apple.com>
Matt Austern <austern@apple.com> writes:
> Consider the following test case:
> struct abc;
>
> template <typename T>
> void foo(T, abc* p)
> {
> p->do_it();
> }
>
> struct abc { void do_it(); };
>
> void invoker()
> {
> abc tmp;
> foo(17, &tmp);
> }
>
> You will notice that struct abc is incomplete at the point of template
> definition but complete at the point of instantiation. The C++
> standard (14.6/7) says: "If a type used in a non-dependent name is
> incomplete at the point at which a template is defined but is complete
> at the point at which an instantiation is done, and if the
> completeness of that type affects whether or not the program is
> well-formed or affects the semantics of the program, the program is
> ill-formed; no diagnostic is required."
>
> So we are within our rights either to accept this code or to reject
> it. Arguably the latter is the better choice, since diagnosing
> ill-formed code is a Good Thing.
>
> On the other hand, in 3.3 we used to accept this code, and I suspect a
> number of other compilers did too. (That's what'll happen if you do
> all name lookup at the point of instantiation.) I suspect there's
> still code out there that relies on the old behavior. Should we
> provide a switch that'll get the old behavior back?
As a C++ programmer I would prefer this be an error by default, with
(if possible) a message explaining that this is now an error
because gcc has changed to match the 1998 standard in this
respect. Issuing no diagnostic, and then having odd behavior at
runtime, would be in my opinion the worst thing to do. Right now,
g++ 3.4 says:
g++-3.4 -W -Wall aus.cc
aus.cc: In function 'void foo(T, abc*)':
aus.cc:6: error: invalid use of undefined type 'struct abc'
aus.cc:1: error: forward declaration of
I consider this almost right - I would appreciate it if g++ would also
mention that this code is ill-formed according to ISO C++ 1998.
If there were resources availible, it would be great to also have a
switch, say, -fsingle-phase-lookup, or something, that emulated
gcc 3.3 instantion & lookup semantics as closely as possible, but
I don't want to see this kind of code handled by a special case
with default compiler switches.