What does it exactly mean when the Standard states
$7.3.1.1/2 - "Th开发者_如何学Goe 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)
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.
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.)
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.
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.
精彩评论