stk
stk

Reputation:

defining structures globally in c++

there was a somewhat detailed thread (228684) on how to globally (using extern struct) declare a structure that could be seen in more than 1 c++ file, but I can not figure out exactly how to do it (there was a lot of discussion about do this, do that, maybe do this, try this, etc...).

couuld someone please post a very simple example of how to declare a structure that could be seen in 2 separate c++ files? If I put all my functions in the same file as the main it works fine, but when I try to split the functions out in different files I cannot get it to compile.

Things I am unclear on... Should I typedef the structure? Do I define the structure in a header file and include that header in each c++ source file? Do I need the #ifndef macro in the header file? Do I declare the structure extern in the header?

Upvotes: 1

Views: 12587

Answers (4)

aib
aib

Reputation: 47031

If you want a global variable; a single struct accessible from multiple compilation units (C++ files):

/* foo.h */
#ifndef EXAMPLE_FOO_H
#define EXAMPLE_FOO_H

struct foo {
    int a;
    int b;
};

extern struct foo globalFoo;

#endif /* EXAMPLE_FOO_H */

--

/* foo.cpp */
#include "foo.h"

struct foo globalFoo = { 1, 2 };

--

/* bar1.cpp */
#include "foo.h"

int test1()
{
    int c = globalFoo.b; //c is 2
}

--

/* bar2.cpp */
#include "foo.h"

int test2()
{
    int x = globalFoo.a; //x is 1
}

The "struct {}" line in foo.h tells the compiler what struct foo looks like. The "extern struct" line declares a particular struct foo called "globalFoo" with external linkage. (It is possible to combine these two declarations, see @litb's answer.) What this means is that users of globalFoo (bar1/test1 and bar2/test2) will look for the struct elsewhere, they will not have their own seperate copies.

foo.cpp is the special case that defines globalFoo. There can only be one definition of any variable, and in this case foo.cpp has globalFoo's definition. When bar1 and bar2 look for globalFoo "externally," they will find foo.cpp's globalFoo. The name will refer to the same actual struct in all three files.

If the extern hadn't been there, then all three .cpp files would have a line that read "struct foo globalFoo;" (Remember, #include is just copy/paste) That would [attempt to] create three different structs with the same name, resulting in a mess.

Note: The "extern struct foo globalFoo;" line is redundant in foo.cpp's case, but that doesn't matter.

Upvotes: 2

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507393

Structures cannot be extern or static. If you want to have a structure used in more than two translation units, put the structure definition into a header:

foo.hpp

struct foo {
    int a;
    int b;
};

Then include that header file into all source files using that struct. Having a struct/class/union defined in multiple source-files is perfectly valid, as long as each one is same defined. You can put a Include Guard around the definition of foo to prevent that foo is included twice into the same sourcefile being compiled. (So, having multiple foo in the same program is valid, but having multiple foo in the same source (note: meaning translation unit) is not valid.) See 3.2 One Definition Rule in the C++ Standard or a Draft.

When you see this:

extern struct foo { int a; int b; } b;

Not the foo is extern, but the b (the object) is extern! It's saying that b is not defined, but merely declared, so you can refer to it.

Upvotes: 3

David Nehme
David Nehme

Reputation: 21597

It's called a header file.

in your header file (call it foo.h)

#ifndef FOO_H
#define FOO_H
class X {
};
#endif

Then, in any C files you have

#include "foo.h"
X x;

For C++ it's more common/preferred to use class, but you can use struct as well. The extern keyword generally refers to variables, not class/struct declarations. You would make a global variable extern in a header file (then declare it not-extern) in one of your .cpp files.

Upvotes: 7

Ben Collins
Ben Collins

Reputation: 20686

Here's a little example:

#ifndef __my_header__
#define __my_header__

class my_class
{

};

#endif

The class my_class will be visible in any file that includes this header. I think there is something else to your question, though, but I don't quite see what.

Upvotes: 0

Related Questions