Thread: static const

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    596

    static const

    Is it sufficient to declare a global variable (which will be defined in a separate header file and #included in the implementations of various classes -- to be used as a constant in various methods) as just:
    const int foo;
    or is there some reason to declare it as:
    static const int foo;

    I've seen some code where "static" is used in this context, but I don't see any reason for it, and haven't noticed any difference in running the code either way. Does "static" have any significance in this context?
    Last edited by R.Stiltskin; 04-12-2008 at 02:08 PM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    const member could be different for different instanses of the class
    static const member is the same for all instanses...

    on the other hand global var declared static has a different meaning - as visible only in the current module - and as so has a little meaning to be declared in the header file...

    but still - in this case you get different instances of the var for any module you include your header... I don't really see a way to initialize it differently though...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    I'm not sure I understand your answer.

    Suppose I have
    const int g_var 5;
    defined in "projroot/common/globvars.h
    and
    #include "../../common/globvars.h"
    in, say, 2 different implementation files: "projroot/module1/class1.cpp" and "projroot/module1/class2.cpp", so g_var is not a member of either class, but is used in member functions of both classes.

    The question is:
    would declaring g_var as "static const int g_var 5" be any different from "const int g_var 5" in THIS CONTEXT (i.e. a non-class-member variable).

    And by the way, does this arrangement REALLY mean that I get 3 copies of g_var? Or do the compiler & linker handle this sensibly & link all 3 classes to the same single copy of g_var?

    This code structure is recommended in FAQ
    http://faq.cprogramming.com/cgi-bin/...&id=1043284392
    but the static/const question is not addressed there.
    Last edited by R.Stiltskin; 04-12-2008 at 06:34 PM.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    "static" in this case means "internal linkage" -- no other file can see that variable. So class1.cpp and class2.cpp would each have their own g_var variable, which would collide if you tried to link them together. (And if you had a main.cpp, it wouldn't have a g_var at all, unless you also included the header there, in which case you'd have a third, different, g_var.)

    What you're supposed to do here is use "extern" in the header (which means "this variable exists, somewhere, and we'll figure out where later") and then in one and only one .cpp file actually do const int g_var = 5.

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by tabstop View Post
    ... class1.cpp and class2.cpp would each have their own g_var variable, which would collide if you tried to link them together.
    I don't get this. If class1.cpp and class2.cpp each have their own g_var, and each of them has file scope, where's the conflict?
    And would this be any different if g_var was declared as just "const int" instead of "static const int"?


    Quote Originally Posted by tabstop View Post
    ... What you're supposed to do here is use "extern" in the header (which means "this variable exists, somewhere, and we'll figure out where later") and then in one and only one .cpp file actually do const int g_var = 5.
    So I should have a globals.h in which I declare each global variable (and also, I guess, global top-level functions) as extern, and a globals.cpp in which I define each global variable and top-level function?

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by R.Stiltskin View Post
    I don't get this. If class1.cpp and class2.cpp each have their own g_var, and each of them has file scope, where's the conflict?
    And would this be any different if g_var was declared as just "const int" instead of "static const int"?
    Okay, not the right word. They won't cause a linker error, they just won't be the same variable. (If you set one to 6, the other to 4, no complaining -- but you'll have to remember which is which and it gets all confusing.)

    Quote Originally Posted by R.Stiltskin View Post
    So I should have a globals.h in which I declare each global variable (and also, I guess, global top-level functions) as extern, and a globals.cpp in which I define each global variable and top-level function?
    No such thing as global functions. But that header / cpp is fine I suppose. You did see the thread about why global variables are eeeeeeeeeeeeeeevil, right? (As long as you know what you're doing, we'll let you do it.)

  7. #7
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by tabstop View Post
    No such thing as global functions. But that header / cpp is fine I suppose. You did see the thread about why global variables are eeeeeeeeeeeeeeevil, right? (As long as you know what you're doing, we'll let you do it.)
    Maybe I used the wrong word. What would you call a utility function - say a function for parsing a particular kind of input file - that is used in implementations of various classes, but is not a member function of any class?

    As to global variables, I have constants that are used in multiple classes in various modules, and they all must use the same value. If I have to change one of those values throughout the project I shouldn't have to search through 15 files looking for all the instances of it, right?

    And what about "static". In this type of arrangement, I've seen some people use just "const", and others use "static const", and both seem to work the same. Is there any difference?

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If they're all constant, then that's the best way to go. If the header is included in every single file, then I can't see that static is going to make much difference. Of course, you can't do extern and static together.

    As to the functions: utility is ok. I would probably (in my head) call such a thing a "library" function, the idea being that all the file/input parsing functions would make up a library. No, I don't usually actually make .lib files out of them.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No such thing as global functions.
    Actually, there is, in the sense that the term can refer to functions in the global namespace.

    What would you call a utility function - say a function for parsing a particular kind of input file - that is used in implementations of various classes, but is not a member function of any class?
    A free function, also known as a non-member function, and since it is a "utility function" instead of being part of the published interface of the class, quite definitely a non-member non-friend function.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Well, for what it's worth, I wasn't able to use extern for this purpose. There are several constants that are used to define array sizes in other files (in other directories, in fact). For these, I got "data member may not have variably modified type" errors, even though they were declared as extern const int in the header and const int in the .cpp file. After I changed those back to const int in the header file and eliminated them from the consts.cpp file, those errors went away, and then I simply got "undefined reference" errors for the rest.

    Just to clarify what I was trying, I declared the various constants as extern const int in a header file, defined them in a source file, added that source file to my makefile, and #included the header file in the files that use those constants. The source file containing the constants definitions was compiled without errors; all the "undefined reference" errors occurred during linking of the source files that use the constants.

    So I eliminated the constants source file, and declared/defined all of the constants as const int in the header file. None of the variables are declared as static. I found several references stating that static is deprecated for variables in namespace scope. I think that applies here. Anyway, it seems to be working correctly.
    Last edited by R.Stiltskin; 04-13-2008 at 01:05 AM.

  11. #11
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Well, I remembered that I started a similar thread a few months ago, so I went back & re-read that one & so now I can eliminate the linker errors just by #including the const header file in the const source file (although it still seems strange to do that since the source file has complete definitions for everything in it).

    But the constants that are used in other files to provide array dimensions still have to be fully defined in the const header file (i.e. NOT as extern). Otherwise the compiler gives that "error: data member may not have variably modified type".

    Any comments on that?

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Arrays must have a fixed size at compile time. If the variable is "extern," then the compiler cannot determine the size at compile time, only possible, at link time, so that's why it won't work.
    If all you want is a global variable that is constant, ie const, then all you need to do is put it in globals.h and include it everywhere. It should work since the compiler can utilize it as a constant expression as long as you don't do anything such as take the address of the variable.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by R.Stiltskin View Post
    Is it sufficient to declare a global variable (which will be defined in a separate header file and #included in the implementations of various classes -- to be used as a constant in various methods) as just:
    const int foo;
    or is there some reason to declare it as:
    static const int foo;
    In C++ global constants are folded at link time, just like templates. There is no need to use "static" since there is no link conflict in the first place. And there are obscure reasons why using static might actually cause problems, but those reasons are unimportant -- the bottom line is, it is not necessary.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function template has already been defined
    By Elysia in forum C++ Programming
    Replies: 19
    Last Post: 04-14-2009, 10:17 AM
  2. Drawing Program
    By Max_Payne in forum C++ Programming
    Replies: 21
    Last Post: 12-21-2007, 05:34 PM
  3. Memory leak - need help finding
    By ChadJohnson in forum C++ Programming
    Replies: 8
    Last Post: 04-06-2005, 07:26 PM
  4. Problem with Template Function and overloaded equality operator
    By silk.odyssey in forum C++ Programming
    Replies: 7
    Last Post: 06-08-2004, 04:30 AM
  5. opengl program as win API menu item
    By SAMSAM in forum Game Programming
    Replies: 1
    Last Post: 03-03-2003, 07:48 PM