Jump to content


Sharing Global Values in multiple object files


  • You cannot reply to this topic
13 replies to this topic

#1 erkokite

    New Member

  • Members
  • PipPip
  • 12 posts

Posted 28 October 2005 - 04:37 AM

Ok, I have 3 files:

test.h:
int b;

void output();

test.cpp:
#include <iostream>

using namespace std;

#include <test.h>


void output(){
	cout<<b<<endl;
}


main.cpp:
#include <iostream>

using namespace std;

#include <test.h>

int main()
{
    b=2;
    output();
    return 0;
}

I need to share the value for the variable, b, between main.cpp and test.cpp, so that output() outputs the value 2. Is there any way to do this?

#2 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 28 October 2005 - 05:14 AM

Define int b in test.cpp and then declare it as extern in test.h that is included in main.cpp

corey

#3 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 28 October 2005 - 06:06 AM

What I like to do is something like this.

globals.h:
#ifndef GLOBALS_H
#define GLOBALS_H

#ifdef DECLARE_GLOBALS
#define GLOBAL
#elif
#define GLOBAL extern
#endif

GLOBAL int foo;
GLOBAL CMyClass bar;
// ...

#endif

Then in main.cpp I do
#define DECLARE_GLOBALS
#include "globals.h"

whereas in other files I just include the globals.h file normally. This lets me use one line of code for each variable (avoids duplicating code) and automatically manages the externs and declarations.
reedbeta.com - developer blog, OpenGL demos, and other projects

#4 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 28 October 2005 - 08:30 AM

Reedbeta: what if you want to initialize the global objects you're using?
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#5 AticAtac

    Member

  • Members
  • PipPip
  • 84 posts

Posted 28 October 2005 - 11:15 AM

As suggested i would do it this (clean) way:

Test.h:

extern int b;

Test.cpp:

int b = <Init Value>;


Any other files (main.cpp) just include Test.h and everything is ok !

#6 erkokite

    New Member

  • Members
  • PipPip
  • 12 posts

Posted 28 October 2005 - 02:59 PM

Is there a way to use a custom type like this:


struct test{

     int a;

};


extern test t1;


I can get single variables to work, but I can't get structs to work. Any ideas?

#7 eddie

    Senior Member

  • Members
  • PipPipPipPip
  • 751 posts

Posted 28 October 2005 - 08:07 PM

That should work.

Something like this:

main.h


struct test

{

    int a;

};



main.cpp

#include <iostream>

using namespace std;


extern test t1;


int main(void)

{

    cout << "Got: " << t1.a << endl;

    return(0);

}



main2.cpp

#include "main.h"


test t1;



Now, that said, a couple of things about style.

I'm not big on global variables personally, but when they are needed, I'm much happier with implementing the Singleton pattern. This pattern will let you control *when* your variable is initialized, which is really important in the cases where you have globals that require use of one another, as well as provide a class-like interface to retrieving and utilizing the variable.

A simple singleton pattern:



class test

{

public:

    static test *Get()

    {

        if(m_pTest == NULL)

        {

            m_pTest = new test;

        }

        return m_pTest;

    }


    void Shutdown()

    {

        if(m_pTest != NULL)

        {

            delete m_pTest;

        }

    }


    int GetA() const { return m_A; }

    void SetA(const int A) { m_A = A; }


private:

    test() {}; // private constructor, so noone else can create

    static test *m_pTest; // Static instance of this object.


    int m_A;


};



Then in a CPP file you add:


test *test::m_pTest = NULL;


And you're done. :)

You use it by doing the following:



int main(void)

{

    test *pTest = test::Get();


    pTest->SetA(1);

    pTest->GetA();

    // etc.


    pTest->Shutdown();


    return 0;

}



Not sure if that helps or not, but I find it's very useful for larger structures that you want global. (Game-wide state information, rendering layers, etc).

Cheers!

#8 Rydinare

    New Member

  • Members
  • PipPip
  • 24 posts

Posted 29 October 2005 - 06:03 AM

The extern solution mentioned above is the answer to the problem.

However, certainly globals are not neat and cause lots of problems (tough to manage, require a lot of additional consideration if moving to a multithreaded environment, etc...).

You may want to consider putting all of your "globals" inside of a singleton class (there are still better ways to design it, but it would be an improvement), instead. This will allow you more control, as to where you can single out the problem in one class, versus searching all over the codebase for each instance where you have an issue.

#9 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 29 October 2005 - 07:01 AM

@.oisyn: obviously I can't include initializers with this scheme (unless I were to modify the macro to allow this, which would be ugly), but I find that I usually don't need compile-time initializations for global variables; and the advantage of this scheme, that I don't have to maintain two separate declarations (the extern and the non-extern ones), seems to outweigh this inconvenience at least for me.
reedbeta.com - developer blog, OpenGL demos, and other projects

#10 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 30 October 2005 - 12:05 AM

Quick nitpick on Reedbeta's suggestion: "declarations" introduce identifiers to the compiler, whereas "definitions" may actually introduce content in the generated code. I can't remember the exact wording in the C++ standard, but it's along those lines. Thus, the DECLARE_GLOBALS macro would be more appropriately named DEFINE_GLOBALS.

#11 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 30 October 2005 - 12:12 AM

Jare said:

Quick nitpick on Reedbeta's suggestion: "declarations" introduce identifiers to the compiler, whereas "definitions" may actually introduce content in the generated code. I can't remember the exact wording in the C++ standard, but it's along those lines. Thus, the DECLARE_GLOBALS macro would be more appropriately named DEFINE_GLOBALS.
Both are declarations, neither is a definition in that context.

Ah but you meant the use. extern variable is a declaration unless it includes an initializer then it is a definition.

corey

#12 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 30 October 2005 - 01:46 AM

Actually, I was wondering whether declare or define was the right term in that context =D It sounds weird to me to say "define a variable", though; as far as I can remember, variables are always declared, while functions and classes are defined.
reedbeta.com - developer blog, OpenGL demos, and other projects

#13 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 30 October 2005 - 03:53 AM

Reedbeta said:

Actually, I was wondering whether declare or define was the right term in that context =D It sounds weird to me to say "define a variable", though; as far as I can remember, variables are always declared, while functions and classes are defined.
An extern variable is declared unless it has an initializer.
Other non-static-class variables are defined with/without initializer.

A function is defined if it includes a body.

A class is defined under similar requirements.

If it will help you understand, I can post the first 2 paragraphs of [basic.def] :

A declaration (clause 7) introduces names into a translation unit or redeclares names introduced by previous
declarations. A declaration specifies the interpretation and attributes of these names.

A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it
contains the extern specifier (7.1.1) or a linkage-specification24) (7.5) and neither an initializer nor a
function-body, it declares a static data member in a class declaration (9.4), it is a class name declaration
(9.1), or it is a typedef declaration (7.1.3), a using-declaration (7.3.3), or a using-directive (7.3.4).

corey

#14 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 31 October 2005 - 09:51 AM

And in code:
void f();  // function declaration
void f()  // function definition
{
}


extern int foo;  // variable declaration
int foo; // variable definition

class S; // class declaration
class S  // class definition
{
    void foo(); // member function declaration within a class definition
};

void S::foo() // member function definition, also implementation
{
}

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users