26
namespace N
{
   static int x = 5;
}

What could be the importance/use-cases of declaring having a static variable at namespace scope?

unholysampler
  • 17,141
  • 7
  • 47
  • 64
User29729
  • 263
  • 1
  • 3
  • 4
  • 1
    I believe that the use of `static` is discouraged; use unnamed namespaces instead. – ereOn May 17 '11 at 17:24
  • 1
    @ereOn: Not really. C++03 had deprecated its usage, but C++11 has undeprecated it. Why? Because its useful in some way. – Nawaz May 17 '11 at 17:39

6 Answers6

40

static variable at namespace scope (global or otherwise) has internal linkage. That means, it cannot be accessed from other translation units. It is internal to the translation unit in which it is declared.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 12
    This is a better answer, as it explains what `static` does in namespace scope. It doesn't do nothing, and it's not useless. – John Dibling May 17 '11 at 17:38
14

Annex D (Compatibility features) [C++03]

D2: The use of the static keyword is deprecated when declaring objects in namespace scope.

Use unnamed namespaces instead as mentioned in this post.

static keyword imparts internal linkage to variables/objects in C as well as in C++ in namespace scope as others have mentioned in their posts.

P.S: Thie feature has been undeprecated as per the latest draft (n3290). In n3225 §7.3.1.1/2 is present but striked out.

Community
  • 1
  • 1
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • +1, Also, while there is no particular reason why this cannot be done with unnamed namespaces, some compilers provide more diagnostics for `static` linkage functions (like warnings when the symbol is unused in the translation unit) – David Rodríguez - dribeas May 17 '11 at 18:37
2

I agree with Nawaz's answer: static keyword is not totally useless in namespaces : it defines that the variable is of internal linkage to the translation unit.

For example : header.h

namespace test{
    static int i = 5;//definition is here.And there will be no multiple definition!
    void set_i();
    void print_i();
}

header.cpp

#include "header.h"
#include "iostream"
void test::set_i()
{
    i = 10;
    return;
}

void test:print_i()
{
    using namespace std;
    cout << "print_i is " << i << endl;
    return;
}

main.cpp

#include "header.h"
#include "iostream"
using std::cout;
int main()
{
    test::i = 20;
    test::set_i();
    cout << "i is " << test::i << endl; 
    test::print_i();
    return 0;
}

Use g++ -std=c++11 header.cpp main.cpp to compile it, and you won't get multiple definition error.If you remove the static keyword and compile it, it is definitely multiple definition error. And please do run the program and observe the result and you may be surprised.

static keyword makes every cpp implementation file(translation unit) which includes the interface header that contains namespace declaration has a internal-linkage copy of the static variable. So even you define that variable in namespace, if it is static keyworded, there will be no multiple definition error.(The same for const with no extern preceding it which define variable of internal linkage, and that's how macros can be discarded in C++) So the saying that variables defined in namespace are implicitly static is wrong and static are not totally useless in namespace. Because every translation unit have one copy of that variable, space is consumed.

However, unnamed namespace can make class declaration inside it inaccessible from other translation unit while static keyword can not "attribute" a class, so that is one advantage of unnamed namespace. Besides, you can use unnamed namespace in nested namespace for variable access restriction. Unnamed namespace are designed for protecting locality rather than offering interface.

Han XIAO
  • 1,148
  • 9
  • 20
1

C++ Standard §7.3.1.1/2:

The use of the static keyword is deprecated when declaring objects in a namespace scope (see annex D); the unnamed-namespace provides a superior alternative.

Unless the unnamed namespace provides a superior alternative in the future Standard it will be undeprecated to achieve C compatibility.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
  • 4
    Hasn't this been undeprecated in 2011? –  May 17 '11 at 17:27
  • 1
    I believe the C++0x standard un-deprecates `static` in this context, does it not? – Fred Larson May 17 '11 at 17:28
  • In the last draft this paragraph is present but striked out , so I'm not sure. – Kirill V. Lyadvinsky May 17 '11 at 17:30
  • Interesting. I guess you can't take anything for granted with a standard that hasn't been finalized. – Fred Larson May 17 '11 at 17:38
  • Can someone post a link to the latest draft? I'm b*ggered if I can work it out from the website! –  May 17 '11 at 17:39
  • @Neil : As per n3290 this feature has been undeprecated. In n3225 I could see this paragraph striked out. – Prasoon Saurav May 17 '11 at 17:40
  • @Prasoon Can you post a link to the draft - my web-foo seems to have gone into decline. –  May 17 '11 at 17:42
  • In the last draft I have handy (from 29 March, 2010), this sentence is still present, albeit in a modified form: the word "objects" has been replaced by "variables". (Maybe in a later draft?) – James Kanze May 17 '11 at 17:43
  • @Neil : Here is the link : http://open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3290.pdf – Prasoon Saurav May 17 '11 at 17:45
  • @Neil: FWIW, whenever I need it I just go to the [tag's info](http://stackoverflow.com/tags/c%2b%2b0x/info), where I hope someone else who can find that stuff has linked it. – GManNickG May 17 '11 at 18:00
  • @James the link prassoon gives is 11-April-2011 and it is not deprecated in that. –  May 17 '11 at 18:05
  • @James I seem to remember a comment from BS that deprecation was a bad idea in the first place because it damaged C compatibility. And I've always preferred static to anonymous namespaces myself. –  May 18 '11 at 07:41
  • @Neil OK. I understand BS' comment. With regards to preferences: what do you do about class definitions, which can't be declared static? – James Kanze May 18 '11 at 10:08
  • @James Classes have TU scope by default, don't they? –  May 18 '11 at 21:47
  • 1
    @Neil Scope isn't an issue; `static` doesn't affect scope. "Classes" (that is: the name of the class, and the names of all of its members) have external linkage unless they are local (defined in a function). Thus, if I define `class C { public: C(); };` in my translation unit, and you do the same, `C::C` refers to the same entity in both. And if we both define it, we'll likely get a duplicate definition when linking. (Formally, it's undefined behavior.) And there's no way you can make `static` apply to a class; that's really why unnamed namespaces were introduced. – James Kanze May 19 '11 at 07:01
  • @James Yes - I don't know what was going through my mind there! –  May 19 '11 at 07:49
0

Same as that of declaring a static in a global namespace but just local to a particular namespace.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

What others already said, with an additional subtlety: static introduces internal linkage, and anonymous namespaces do not.

Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88