20
// MyClass.h

namespace MyNamespace {

  static const double GasConstant = 1.987;

  class MyClass
  {
    // constructors, methods, etc.
  };
}

I previously had GasConstant declared within the MyClass declaration (and had a separate definition in the source file since C++ does not support const initialization of non-integral types). I however need to access it from other files and also logically it seems like it should reside at the namespace level.

My questions is, what effect does static const have in this case? Clearly const means I can't assign a new value to GasConstant, but what does a static member at the namespace mean. Is this similar to static at file scope, where the member is not accessible outside of the unit?

James Hopkin
  • 13,797
  • 1
  • 42
  • 71
mindless.panda
  • 4,014
  • 4
  • 35
  • 57
  • Is this in a header file (.h) or in an implementation file (.cpp) ??? – AnT stands with Russia May 21 '10 at 16:58
  • 3
    In C++ there is no file scope. There are only namespace scopes in C++ if you are outside functions and classes. Also if you read on some pages what they call "global", they usually mean the global namespace and other namespaces included. `cplusplus.com` is known for its inaccurate use of the word "global", for instance. So if something explains the effects of "static" in "global scope", they usually mean its effect in namespace scope. – Johannes Schaub - litb May 21 '10 at 17:48

3 Answers3

12

The use of static at namespace scope is was* deprecated in C++. It would normally only ever be seen in a source file, where its effect is to make the variable local to that source file. That is, another source file can have a variable of exactly the same name with no conflict.

In C++, the recommended way to make variables local to the source file is to use an anonymous namespace.

I think it's fair to say the static in the header in your code is simply incorrect.

*As pointed out by Tom in the comments (and in this answer), the C++ committee reversed the decision to deprecate static use at file scope, on the basis that this usage will always be part of the language (e.g. for C compatibility).

Community
  • 1
  • 1
James Hopkin
  • 13,797
  • 1
  • 42
  • 71
  • 1
    Recommended way to do this.... what exactly do you mean by "this"? I'm not sure its clear to me. – mindless.panda May 21 '10 at 17:45
  • 1
    The decision to deprecate static at namespace level is no more: http://stackoverflow.com/questions/4726570/deprecation-of-the-static-keyword-no-more, which makes this answer incorrect, as now using anonymous namespaces or static are two accepted and correct ways to achieve the same thing. – Tom Feb 17 '16 at 14:10
  • Thanks for the update, @Tom - I'll update the answer. – James Hopkin Feb 17 '16 at 15:02
4

MSDN says:

When modifying a variable, the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).

Remember that including header files means to replace the "#include"-directive with the actual code of the header file. So, the static variables will be visible only in the ".cpp" (which is compiled) file that includes the two header files.

So each "cpp"-file including the headers will have it's own static variable.

Community
  • 1
  • 1
Simon
  • 9,255
  • 4
  • 37
  • 54
  • Now I've declared/defined GasConstant in a Constants.h which is included into MyClass.h. Sounds like it will only be visible in files that include Constants.h or MyClass.h, and not from any other file that doesn't. What happens if another file includes both? – mindless.panda May 21 '10 at 16:44
  • 3
    Each .cpp file will get its own, independent copy. May very well not be what you want...or maybe it is. For .cpp files that include both, this shouldn't change anything but you'll of course need the proper header protections. – Edward Strange May 21 '10 at 16:48
  • So sounds like what I want to do is simply make it const. – mindless.panda May 21 '10 at 17:33
2

If this is a header file, then static has no effect in this case. const objects already have internal linkage by default in C++, so whether you declare it with static or without static makes no difference whatsoever.

I assume you simply moved the declaration from the class into the namespace. But static has totally different meaning in the context of the class declaration and in the context of namespace. Inside the class, you needed static. In the namespace the static is superfluous.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • but isn't it the case that separate files that included the header would have separate instances of the namespace member as a result of static operating similar to file scope static? This won't matter of course since its const, i.e. this would be a problem if I thought the two files had access to the same member and updating from one would be reflected in the other. Just trying to keep it straight. – mindless.panda May 21 '10 at 17:47
  • 1
    In fact, he doesn't need `static` in the class. With it and without it, both are invalid for `double` :) – Johannes Schaub - litb May 21 '10 at 17:52
  • 1
    Actually it *can* matter. `Template` will be an ODR violation if it is instantiated in two translation units. – Martin Bonner supports Monica Apr 11 '18 at 12:51
  • [C++17 n4659 standard draft 6.5 "Program and linkage"](https://stackoverflow.com/questions/12042549/define-constant-variables-in-c-header/53541011#53541011). – Ciro Santilli OurBigBook.com Nov 29 '18 at 14:17