Topic: Forward declaration of typedef via "class T;" valid?


Author: jamshid@ses.com (Jamshid Afshar)
Date: Fri, 18 Feb 1994 18:49:57 GMT
Raw View
Redirected to comp.std.c++.

In article <2k0ek7$k43@seattle.polstra.com>,
John Polstra <jdp@polstra.com> wrote:
> class T;  // T is a type name
> class C { /*...*/ };
> typedef C T;  // Now fully declare T as a typedef to C.
> T *p = 0;
>
>To me, the ARM seems to say that it should work -- essentially because a
>type name is a type name is a type name, no matter whether it's a struct
>tag or a class tag or a typedef name.

Coincedentally this same problem came up yesterday at work.  My
immediate reaction was that it's not legal, and I still believe that,
but it's definitely more complicated than I had thought.  ARM 7.1.3:
"A typedef may not redefine a name of a type declared in the same
scope to refer to a differnt type."  The question is whether `class
T;' declares T to as a unique, different type than the following
`class C' declaration.  A compiler can't assume that T might later be
typedefed to class C:

 class T;
 class C {/*...*/} c;
 T* p = &c;  // compiler must give error here
 //...

ARM 9.1: "An elaborated-type-specifier with a class-key used without
declaring an object or function introduces a class name exactly like a
class declaration...".  My feeling is that the first `class T;' does
declare T as a unique class.  It would definitely be an error to
declare "class T;" after its ben typedef'd.

 class T;
 class C {/*...*/};
 typedef C T;
 class C; // okay
 class T; // error: ARM 7.1.3 "The synonym may not be used
          // after a class ... prefix [or as ctor/dtor name]"

It would be very strange for C++ to disallow `class T;' when it was
allowed before some other declarations.  I don't think I've adequately
proved anything either way, so a definitive answer would be
appreciated.

Btw, here's something I never noticed before.  ARM 7.1.3 allows
multiple typedefs to declare the same name as long as its defined as
the same type:

 typedef struct s {/*...*/} s;
 typedef int I;
 typedef int I;
 typedef I I;
 typedef int* IPtr;
 typedef I* IPtr;

As far as I know, code like this isn't legal ANSI C (except maybe the
declarations of `s').  I didn't notice any mention of this in ARM 18,
though.

Jamshid Afshar
jamshid@ses.com




Author: jdp@polstra.com (John Polstra)
Date: 19 Feb 1994 11:28:44 -0800
Raw View
In article <CLFoBA.86u@ses.com>, Jamshid Afshar <jamshid@ses.com> wrote:
> In article <2k0ek7$k43@seattle.polstra.com>,
> John Polstra <jdp@polstra.com> wrote:
> > class T;  // T is a type name
> > class C { /*...*/ };
> > typedef C T;  // Now fully declare T as a typedef to C.
> > T *p = 0;
>
> ... My immediate reaction was that it's not legal, and I still believe
> that...

I also think it's not legal.  One complication that would argue against
allowing it concerns typedefs to functions.  If it can assume that T is
a class, then the compiler knows enough to manipulate pointers to T,
because all class pointers are guaranteed to be the same size.  But if T
is a typedef, then it might refer to a function.  And a pointer to a
function is allowed to be a different size than a pointer to a class.

It could still me made legal, by having the compiler check at the
typedef to make sure that T is not being declared as a function type
after previously having been stated to be a class.  But ... ugliness
creeps in ...

> Btw, here's something I never noticed before.  ARM 7.1.3 allows
> multiple typedefs to declare the same name as long as its defined as
> the same type:
>
>  typedef struct s {/*...*/} s;
>  typedef int I;
>  typedef int I;
>  typedef I I;
>  typedef int* IPtr;
>  typedef I* IPtr;
>
> As far as I know, code like this isn't legal ANSI C (except maybe the
> declarations of `s').  I didn't notice any mention of this in ARM 18,
> though.

You're right, it's not legal in ANSI C.  That's why you see all those
ugly preprocessor guards around the typedefs in the standard include
files.  Ick.  I'm glad that got changed in C++.
--
   John Polstra                                       jdp@polstra.com
   John D. Polstra & Co., Inc.                  ...!uunet!polstra!jdp
   Seattle, Washington USA   Phone (206) 932-6482, FAX (206) 935-1262
   "Self-knowledge is always bad news."                 -- John Barth