# struct in multiple files

10 replies to this topic

### #1thebigT

New Member

• Members
• 18 posts

Posted 02 December 2010 - 08:59 AM

### #2Sol_HSA

Senior Member

• Members
• 517 posts
• LocationNowhere whenever

Posted 02 December 2010 - 09:06 AM

First off, you can use more than one #include line, so if you have something that's needed everywhere, just put it in a separate include file and include that from either all the header files that need it.

To avoid issues with multiply-included files, you can use the common include guards:

#ifndef THISHEADER

... the header stuff here ...

#endif

that way, if the file gets included several times (from various header files, for instance), the contents will only get used once. the THISHEADER has to be unique for every header file; a common way is to name it HEADERFILE_H for headerfile.h and OTHERFILE_H for otherfile.h etc.

This is the easy way to do it. More preferable ways include source-side include guards, forward declarations in case the data structure is only used via a pointer, and preferably never including from include files, but those really become issues only when your project grows so large you start to worry about build times..
http://iki.fi/sol - my schtuphh

### #3.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 02 December 2010 - 01:31 PM

I think his problem has more to do with circular dependencies

// A.h
struct A
{
B * ptr;
};

// B.h
struct B
{
A * a;
};

Of course you could include A.h from B.h, and include B.h from A.h, but if you include A.h, it in turn includes B.h, and there you have a struct definition of B which nees A but which isn't defined at that point.

The solution is, only include what you actually need. The fact of the matter is, A doesn't need the definition of B, and neither does B need the definition of A. Actual definitions are only needed when accessing their members or when the compiler needs to know their size (which is if you use such a struct as a member of another struct). In above example, you only needs pointers. And all pointers are represented in the same way, so the only thing the compiler needs is that there exists an A when you're using a pointer of A.

So, solution:
// A.h
struct B; // declaration of B, the compiler now knows that B exists, but does not know what it contains.

struct A
{
B * ptr;
};

// B.h
struct A;

struct B
{
A * a;
};
It now turns out that neither A nor B needs to include the other header.

That said:

Quote

If the vector struct is nested within another struct definition then it seems to need the vector struct redefined in that header. That's ridiculous! Is this correct?
If you actually mean structs defined within other structs, then you have a problem. As these structs are members, you'll need their encompassing struct definition:
// A.h
struct A
{
struct NestedA { };

B::NestedB * ptr;
};

// B.h
struct B
{
struct NestedB { };

A::NestedA * ptr;
};
Ok, now what? You can't predeclare B in A because you'll need B's definition in order to access B::NestedB. Basically, you're screwed. This is an unsolvable problem in C++*, and you should avoid these kinds of designs.

* Well, not literally unsolvable, you can apply some template trickery and make use of the two-phase name lookup paradigm to delay the lookup of the nested members until the actual use of the type at which point their both fully defined, but I don't recommend it.
-
Currently working on: the 3D engine for Tomb Raider.

### #4Reedbeta

DevMaster Staff

• 5340 posts
• LocationSanta Clara, CA

Posted 02 December 2010 - 06:02 PM

Sol_HSA said:

To avoid issues with multiply-included files, you can use the common include guards:

reedbeta.com - developer blog, OpenGL demos, and other projects

### #5SyntaxError

Valued Member

• Members
• 139 posts

Posted 02 December 2010 - 08:58 PM

Reedbeta said:

I might be wrong but I was under the impression that #pragma once wasn't technically standard. Not that it's a big deal since it seems to be supported a lot.

### #6Reedbeta

DevMaster Staff

• 5340 posts
• LocationSanta Clara, CA

Posted 02 December 2010 - 09:00 PM

It's quite widely supported and if it isn't part of the standard it ought to be, as it's obviously better than #include guards when avalable. :yes:
reedbeta.com - developer blog, OpenGL demos, and other projects

### #7thebigT

New Member

• Members
• 18 posts

Posted 03 December 2010 - 03:35 AM

That's a great help thanks guys.

### #8Sol_HSA

Senior Member

• Members
• 517 posts
• LocationNowhere whenever

Posted 03 December 2010 - 07:52 AM

Reedbeta said:

I was certain someone would find something to whine about, hence the last paragraph.

But yeah, I think include guards plus #pragma once is a better solution than external include guards. Will work everywhere and where the pragma is supported, faster compiles.
http://iki.fi/sol - my schtuphh

### #9.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 03 December 2010 - 03:53 PM

I have never actually seen benchmarks between regular guards and #pragma once, but I thought I read somewhere that some compilers simply recognized the standard include guards and acted as if a #pragma once is in that header (or more specificially it doesn't reparse it when that macro is still defined when it's reincluded).

Reedbeta said:

It's quite widely supported and if it isn't part of the standard it ought to be, as it's obviously better than #include guards when avalable. :yes:
Since it's a #pragma directive it's by definition not in the standard
-
Currently working on: the 3D engine for Tomb Raider.

### #10poita

Senior Member

• Members
• 322 posts

Posted 06 December 2010 - 09:04 AM

.oisyn said:

I have never actually seen benchmarks between regular guards and #pragma once, but I thought I read somewhere that some compilers simply recognized the standard include guards and acted as if a #pragma once is in that header (or more specificially it doesn't reparse it when that macro is still defined when it's reincluded).

I'd be very surprised if any major compilers didn't do this.
Homepage: http://poita.org

### #11genix

New Member

• Members
• 1 posts

Posted 28 January 2011 - 07:05 AM

Hay guys,
heeso is here.I have read this post and also visited the above link.It contains valuable information.I will use this information in future.

#### 1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users