14

What does it exactly mean when the Standard states

$7.3.1.1/2 - "The use of the static keyword is deprecated when declaring variables in a namespace scope (see annex D); the unnamed-namespace provides a superior alternative."

I have referred this but it does not cover what I am looking for.

Is there an example where the superiority is clearly demonstrated.

NB: I know about how unnamed namespaces can make extern variables visible in the translation unit and yet hide them from other translation units. But the point of this post is about 'static namespace scope' names (e.g global static variables)

Community
  • 1
  • 1
Chubsdad
  • 24,777
  • 4
  • 73
  • 129
  • 4
    I think the question you linked to pretty clearly demonstrates the advantages. What *are* you looking for? – Andreas Brinck Nov 18 '10 at 09:33
  • @Andreas Brinck: Nope. I am looking at some code example or situation where static has a disadvantage as compared to unnamed namespace in the context of the quote from the Standard in OP – Chubsdad Nov 18 '10 at 09:37
  • I think you are mis-interpreting the meaning of `global static variables`. The variables are not truly global (they can not be seen outside the translation unit. Note a global variable can be extern or static (not both). – Martin York Nov 18 '10 at 10:38

4 Answers4

11

What does it exactly mean?

Technically deprecated means that a future standard may remove the feature.

In practice that isn't going to happen, because of the need to support old code.

So in practice it means, "strongly discouraged".

Example of superiority of unnamed namespace

An unnamed namespace is generally superior because what you have in that namespace can have external linkage.

In C++98 external linkage is necessary for things that can be template parameters, e.g., if you want to templatize on a char const*, it must be pointer to char that has external linkage.

#include <iostream>

// Compile with "-D LINKAGE=static" to see problem with "static"
#ifndef LINKAGE
#   define LINKAGE extern
#endif

template< char const* s >
void foo()
{
    std::cout << s << std::endl;
}

namespace {
    LINKAGE char const message[] = "Hello, world!";
}  // namespace anon

int main()
{
    foo<message>();
}

That said, it's a bit inconsistent that static isn't also deprecated for functions.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
10

This:

static int func_for_this_file_only() { ... }

is "as good as" this:

namespace { int func_for_this_file_only() { ... } }

but static can't be used for this:

namespace { class class_for_this_file_only { ... } }

Therefore, anonymous namespaces in C++ are more versatile and superior to static.

(I'm sure someone will argue with that conclusion, but as a C hacker I think the anonymous namespace solution is better.)

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
  • interesting. but the standard quote is about 'declaring variables in namespace scope' – Chubsdad Nov 18 '10 at 09:35
  • For the class it helps to enforce the one-definition-rule if a class with the same name is created in a different translation unit with a different context. – CashCow Nov 18 '10 at 09:41
  • @Chubsdad - see @Alf's answer below for what the standard means. IMHO it's a rather technical detail, but C++ has a lot of those (part of the reason I prefer C, but that's not something I should stir up). I think my example is a better argument for namespaces, but his example answers your question more specifically. – Chris Lutz Nov 18 '10 at 09:46
6

Interestingly, ISO/IEC 14882:2011 (C++11) removed this language (in fact, it removes the whole paragraph §7.3.1.1/2). It also removes the mention of static from Annex D.

Thus, using the storage class specifier static to give a name internal linkage still works (§3.5/3) and is no longer deprecated.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
2

The goal is to define a symbol that exists only within your own translation unit. This can be "translation unit global" and may be a variable or a function.

This is commonly used in a class definition file as an alternative to private static class members as the static members have to be declared in the header, but a free-function does not have to be (unless it has to be a friend, which it virtual never actually needs to be, by the way).

The use of static would be:

static size_t BUFSIZE = 2048; // assume not const for this example
static int myCallback( void * ptr );

The use of an anonymous namespace is

namespace {

size_t BUFSIZE = 2048;
int myCallback( void * ptr );

}

The standard is saying that the second construct is preferred. We have found that sometimes it is advantageous still to use static in addition to the anonymous namespace to actually reduce the binary size.

CashCow
  • 30,981
  • 5
  • 61
  • 92