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