Sign in to follow this  

Forward Declarations to Typedefs?

This topic is 4359 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Has anybody else noticed that VC++ in VS.NET 2003 will crash and burn if you try to use a forward declaration to a typedef'd type? You can test this out yourself. Create a main, and 2 others files. In one file create a blank struct called class1. In the other header file create a forward declaration for a class3 and then create a struct that only has one member, a class3 type. In the main file, include the class1 file and then setup the typedef class1 class3, and then include the class2 file. Create an instance of class2 in your main function and compile. You'll get the lovely fatal error C1001: INTERNAL COMPILER ERROR. This is really annoying and I'm currently looking for a workaround. Right now all I can figure is to either drop the typedef all together ( which is not an option ) or to use a preprocessor directive instead of a typedef, which will ruin intellisense and create just generally ugly code. As it stands, I'm having to drop the forward declarations which is annoying since it seriously bloats the compile time. Has this problem been fixed in the express versions? Any ideas on better workarounds?

Share this post


Link to post
Share on other sites
The code is valid and simple. Use a forward declaration to a typedef'd class and then instantiate the class that was using the forward declaration. It will not compile.

Share this post


Link to post
Share on other sites
Why not forward declare the class and then declare your typedef before you use it? If you do it that way, you shouldn't need to use a forward declared typedef.

Share this post


Link to post
Share on other sites
Do you mean something like this ?:

Class1.h

class Class1
{
} ;

Struct1.h

class Class 3 ;
struct Struct1
{
Class3 AMember ;
} ;

main.cpp

#include "Class1.h"
typedef Class1 Class3 ;

int main ()
{
Class3 AClass ;
return 0 ;
}

It compiles fine on my VS 2003.

Share this post


Link to post
Share on other sites
Quote:
Original post by Skeleton_V@T
...


Almost, change that to:

-- Class1.h
class Class1
{
} ;

-- Struct1.h
class Class3;
struct Struct1
{
Class3 AMember ;
};

-- Main.cpp
#include "Class1.h"
typedef Class1 Class3 ;
#include "Struct1.h"

int main ()
{
struct1 str;
return 0 ;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by nimrand
Why not forward declare the class and then declare your typedef before you use it? If you do it that way, you shouldn't need to use a forward declared typedef.


I'm not sure I exactly understand what you mean? If I do understand you, then declaring the class before I use it would completely bypass the purpose of the forward declarations - to speed up compile time. And there is also the issue that there is one typedef and multiple classes uses the typedef'd class. Again, maybe I'm not understanding what you're suggesting?

Share this post


Link to post
Share on other sites
Well you can't declare a member to be an incomplete type. And I can't imagine why you would want to typedef a class to the name of another class, nor could I think of what it might do, if any compiler allows it.

Share this post


Link to post
Share on other sites
Quote:
Original post by RDragon1
Well you can't declare a member to be an incomplete type. And I can't imagine why you would want to typedef a class to the name of another class, nor could I think of what it might do, if any compiler allows it.


Class3 is not an 'incomplete' type or an independant class; it is an alias for class1.

Share this post


Link to post
Share on other sites
Quote:
Original post by haro
[...]Class3 is not an 'incomplete' type or an independant class; it is an alias for class1.
Yes, but class3 is not a class, it's an alias. Typedef does not create new types, it creates new names for old types. I'm not sure, but I don't think what you're doing is valid code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Extrarius
Quote:
Original post by haro
[...]Class3 is not an 'incomplete' type or an independant class; it is an alias for class1.
Yes, but class3 is not a class, it's an alias. Typedef does not create new types, it creates new names for old types. I'm not sure, but I don't think what you're doing is valid code.


Do you know how typedef works? The following is fine:

typedef Vector3 Point;
Point p;

p.blah..

I am doing nothing more than this, only using a forward declaration of the typedef'd type.

Share this post


Link to post
Share on other sites
Ah!! After playing around with the code enough I've found a strange quirk. Taking away the class keyword before the forward declaration and simply leaving the type name works?!?! So make the following change:

-- Struct1.h
Class3; // took away class keyword for forward declaration
struct Struct1
{
Class3 AMember ;
};

And it now compiles and works exactly as desired. What the hell? This is going to be some seriously portable code. [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by haro
Quote:
Original post by Skeleton_V@T
...


Almost, change that to:

/*...*/


Okay, bad news is that the compiler complained INTERNAL COMPILER ERROR to me.
Good news: I've changed it a little, and it compiled fine:
Original
-- Struct1.h
class Class3;
struct Struct1
{
Class3 AMember ;
};


Fixed
- Struct1.h
typedef Class3;
struct Struct1
{
Class3 AMember ;
};
[smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Skeleton_V@T
...


EEP. You and I simultaneously made the same bad mistake. A one parameter typedef is ignored by the compiler. Similarly, my "Class3" is just declaring an unnamed instance of Class3, which is also ignored by the compiler. This only works because the class3 typedef was already in scope. Move the typedef to after the include... [sad]

Share this post


Link to post
Share on other sites
Well google turned out to be my friend. This page has some information on the exact problem I'm talking about. The author of that page recommends the following:

1. Make a single header file for all type defs.
2. In the header file, first forward declare the class that is to be typedef'd.
3. Then typedef the class
4. For any file that uses the forward declarations, include that header file

Not exactly the sort of solution I wanted, but it's looking like it's the only reasonable one. In any case, thanks alot for all the help everybody. I still think this is an interesting design problem though. Surely there is a better method than the above. I'd love to hear if anybody can figure out something better.

Share this post


Link to post
Share on other sites
Also, while I'm on a roll with replying to myself I thought I'd mention why I was doing this in the first place, since I think it's a really useful tool. My situation came from when I was implementing an interface that a large amount of my current project relies on. However, there was another implentation of an identical interface using private code that I do not have access to. I decided I wanted to use the already implemented code, rather than writing it all from scratch myself. Since I did not have direct access to the code for the implemented version, I simply setup 'my' implementation as a typedef of the already implemented version; hence the many files forward declaring my implementation, which was a typedef, resulting in this mess.

Yes, I realize that if the interface for the implemented version I'm using changes, then everything goes down the toilet. But, I know for a fact that it will not. And even more importantly, even if I did the more 'proper' thing by filling out my interface with nothing but calls to the implemented version - I would still have the same problem, but have wasted alot more time!

Share this post


Link to post
Share on other sites
Quote:
Original post by haro
Quote:
Original post by RDragon1
Well you can't declare a member to be an incomplete type. And I can't imagine why you would want to typedef a class to the name of another class, nor could I think of what it might do, if any compiler allows it.


Class3 is not an 'incomplete' type or an independant class; it is an alias for class1.


If it's supposed to be an alias, then WHY are you trying to forward declare it?!



struct A{};
typedef A B; //OK!

------
struct A{};
struct B;
struct C
{
B b; //illegal, B is undefined
};

typedef A B; //makes no sense! illegal, B is a real type!

Share this post


Link to post
Share on other sites

This topic is 4359 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this