Global value in header

This is a discussion on Global value in header within the C++ Programming forums, part of the General Programming Boards category; Hi, I have what I think is a pretty basic question. I need to have a global value defined, prefferably ...

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    158

    Global value in header

    Hi, I have what I think is a pretty basic question. I need to have a global value defined, prefferably in one of my header files. The value should be accessible to all the .cpp files that include that header. The problem with what I tried is that I get errors that the value has already been defined since it is included in each .cpp file. I need something like:

    int programIsActive = 1;

    I need to be able get and set that value from any of the .cpp files. What is the best way to do this?

    (I am already using a #ifndef for the whole contents of the header file but that does not seem to help)

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,592
    In the header, you have
    extern int programIsActive;

    In ONE source file, you have
    int programIsActive = 1;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,667
    The problem with defining variables in headers is that they'll be included in every .cpp file and the compiler generates TWO or more variable_name symbols. Each symbol has to be unique, of course, so the linker complains.
    Thus you need to define them in one .cpp file and tell the compiler that the variable exists in another .cpp file. This is usually done in the header as Salem points out.
    (Of course, the compiler won't check, so if the variable does indeed not exist in another .cpp file, the linker complains.)
    Last edited by Elysia; 11-21-2007 at 08:09 AM.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,674
    If you *really* want to keep it to a single header file, there is a way to do it - but I usually reserve this kind of trickery for when there's a good excuse for it.
    Code:
    inline int& ProgramIsActive()
    {
        static int val = 1;
        return val;
    }//ProgramIsActive
    gg

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Codeplug View Post
    If you *really* want to keep it to a single header file, there is a way to do it - but I usually reserve this kind of trickery for when there's a good excuse for it.
    Code:
    inline int& ProgramIsActive()
    {
        static int val = 1;
        return val;
    }//ProgramIsActive
    gg
    But doesn't that potentially make one global variable for each call to ProgramIsActive() - if the calls are from different source files.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,667
    Though when you're using const, it hardly matters. But when your global var isn't const, this practice shouldn't be used since it wouldn't be global.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Though when you're using const, it hardly matters. But when your global var isn't const, this practice shouldn't be used since it wouldn't be global.
    But none of the above says anything about const, right?

    My guess is that the "global variable" is either a reference count or a boolean to say "have we initialized <something>" - in which case you want to be able to modify it, and it really NEEDS to be ONE variable for everything. I'm obviously not sure what the original post is about, but I've certainly used the method of "a global variable is used to indicate if you need to do something because we got here the very first time".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,674
    Quote Originally Posted by C++ Draft Standard, 7.1.2, paragragh 4
    An inline function shall be defined in every translation unit in which it is used and shall have exactly the
    same definition in every case (3.2). [Note: a call to the inline function may be encountered before its definition
    appears in the translation unit. ] If a function with external linkage is declared inline in one translation
    unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required.
    [Note: a static local variable in an extern inline function always refers to the same object. ]
    It should also be noted that in C++, inline functions have external linkage by default. I don't think this is the case for C. So this is C++ only trickery

    gg

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,667
    Quote Originally Posted by matsp View Post
    But none of the above says anything about const, right?

    My guess is that the "global variable" is either a reference count or a boolean to say "have we initialized <something>" - in which case you want to be able to modify it, and it really NEEDS to be ONE variable for everything. I'm obviously not sure what the original post is about, but I've certainly used the method of "a global variable is used to indicate if you need to do something because we got here the very first time".

    --
    Mats
    I don't think I've used the approach too much. I usually do MFC so that means I'm working with classes. But you're right, of course, I have used the approach sometimes.
    The best thing to do is to avoid that trickery practice.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,674
    This kind "trickery" is typically seen in classes, static member functions, and certain types of singleton patterns.
    In the case of a regular inline function, there's the danger of C code including the header and incorrectly using this construct. We could C++'ize the code to avoid that pitfall.
    Code:
    struct ProgramIsActive
    {
        static int& Value()
        {
            static int val = 1;
            return val;
        }//Value
    };//ProgramIsActive
    The only other rationale I can come up with for avoiding this construct:
    - Older compilers are known not to implement this correctly, but most modern versions do
    - For the simple "global variable in a header" case - the typical construct as Salem describes follows the KISS principle.

    gg

  11. #11
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,246
    The appropriate pattern would be a singleton which contains any and all globally relevant program settings. This way you isolate all such variables to a single piece of code, you're not tempted to scatter various globals throughout different modules (or do it accidentally), and you'll stop hearing complaints about your use of globals Fewer complaints, at least.

    I dislike singletons for the same reasons I dislike globals but if you absolutely have to do it...

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,667
    Or just stuck all globals into Globals.cpp and Globals.h. But the best way is to avoid them globals - use classes and local variables or even arguments.
    I've had few need for a lot of global variables.

  13. #13
    Registered User
    Join Date
    Oct 2007
    Posts
    158
    Hey, I used Salems suggestion and that is working ok. I try to stay away from global variables too but this one I need.

    Thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. IP header "total length" vs. packet size
    By MK27 in forum Networking/Device Communication
    Replies: 2
    Last Post: 01-04-2009, 06:45 AM
  2. Replies: 5
    Last Post: 08-06-2008, 09:59 AM
  3. class header confusion
    By te5la in forum C++ Programming
    Replies: 2
    Last Post: 07-22-2008, 02:39 PM
  4. header and source files
    By gtriarhos in forum C Programming
    Replies: 3
    Last Post: 10-02-2005, 03:16 AM
  5. no... wtf!!!?? ( Global class is 'undeclared' )
    By knave in forum C++ Programming
    Replies: 5
    Last Post: 05-10-2003, 05:41 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21