Using typedef to define a forward declaration

  • Thread starter Christoph Bartoschek
  • Start date
C

Christoph Bartoschek

Hi,

the following code does not work:

class A;
class B {};
typdef B A;

Is there a deep reason why this should not work? Why not allowing the
typedef to resolve the forward declaration as long as the sources match and
as long as the ODR is followed?

A follow-up quesition is: Why is there no way to forward-declare a generic
object type that is later defined to an object type?

With such a forward declaration one could already use pointers till the type
is bound to an object type. Given this one were not forced to use
reinterpret_cast or lots of code in such a situation.

The only reason I can think of is that one would have to extend the linkers
to cope with forward-declarations.

Christoph
 
V

Victor Bazarov

Christoph said:
the following code does not work:

class A;
class B {};
typdef B A;

Is there a deep reason why this should not work?

You mean, besides the fact that it makes no real sense to do that?
You're not using 'A' between the forward-declaration and the typedef.
So, why would you want to forward-declare it? Use an example closer to
real life.

The main question is, what does it buy you?
> Why not allowing the
typedef to resolve the forward declaration as long as the sources match and
as long as the ODR is followed?

There are slightly different requirements to the uses of class-id (or
type-id) and typedef-name, although they may not be playing any
significant roles in your cases. For example, you can't use "class T"
if 'T' is a typedef-name, even if the underlying type is a class. I am
not sure why that is, though. Ask in comp.c++.std for the rationale
behind that limitation in [basic.lookup.elab/2]. There are other
examples of that in the Standard, probably. Look 'em up.
A follow-up quesition is: Why is there no way to forward-declare a generic
object type that is later defined to an object type?

Most likely because the more definitive the declaration, the easier it
is for the compiler to analyse the rest of the code that uses that
symbol and the more efficient and less ambiguous the rules are... My
speculation, of course - I never attempted to write a compiler from such
a complex language like C++.
With such a forward declaration one could already use pointers till the type
is bound to an object type. Given this one were not forced to use
reinterpret_cast or lots of code in such a situation.

The only reason I can think of is that one would have to extend the linkers
to cope with forward-declarations.

Maybe. Your guess is likely better than mine.

V
 
B

Balog Pal

Victor Bazarov said:
You mean, besides the fact that it makes no real sense to do that?

It would make perfect sense to do that, and the miss of such feature is
pretty damn painful.
You're not using 'A' between the forward-declaration and the typedef.

Come on, now ;). Look up the zillion old threads asking why one can't say

class std::string;
or
void foo(class std::string const & str);

not including <string> in the header and write all the declarations riding
the incomplete type -- then when definition or use is due include the
header.
So, why would you want to forward-declare it? Use an example closer to
real life.

people struggling for separation of interfaces and cut dependencies could
quote a big deal of code matching the problem. It breaks transparency
badly, suppose you had the code working with the incomplete type, than at
some point of time, where your class had a separate implementation in a
separate file.

Then you observe that the class is generic enough, and can be made into a
template, the original turining to some Templ<T> that can be put back as a
typedef. And then notice, that the forward declaration is not compatible.

I guess the reason lies with some historic feature of the linkers and name
mangling. Too bad it got not covered ever since. C++0x fixes the related
problem for enums.
 
J

James Kanze

Try interposing some additional declarations:

class A;
void f(A*);
class B{};
void f(B*);
typedef B A;

Have you declared one function, or two?
You mean, besides the fact that it makes no real sense to do
that? You're not using 'A' between the forward-declaration
and the typedef. So, why would you want to forward-declare
it? Use an example closer to real life.
The main question is, what does it buy you?
There are slightly different requirements to the uses of
class-id (or type-id) and typedef-name, although they may not
be playing any significant roles in your cases. For example,
you can't use "class T" if 'T' is a typedef-name, even if the
underlying type is a class. I am not sure why that is,
though. Ask in comp.c++.std for the rationale behind that
limitation in [basic.lookup.elab/2]. There are other examples
of that in the Standard, probably. Look 'em up.
A follow-up quesition is: Why is there no way to
forward-declare a generic object type that is later defined
to an object type?
Most likely because the more definitive the declaration, the
easier it is for the compiler to analyse the rest of the code
that uses that symbol and the more efficient and less
ambiguous the rules are... My speculation, of course - I
never attempted to write a compiler from such a complex
language like C++.

The problem here is simple: you can declare and define pointers
to an incomplete type. So the compiler has to either know the
exact type, or know that it is a class type, so that it can know
the size and the representation of the pointer. You can forward
declare that the type is a class type, but you can't forward
declare that it will be some arbitrary type.
Maybe. Your guess is likely better than mine.

The problem is principly because there exist (or have existed)
systems on which pointers to different types have different
sizes and representations.
 

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