namespace N
{
static int x = 5;
}
What could be the importance/use-cases of declaring having a static variable at namespace scope?
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.
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.
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.
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.
Same as that of declaring a static in a global namespace but just local to a particular namespace.
What others already said, with an additional subtlety: static introduces internal linkage, and anonymous namespaces do not.
Related
I totally understand the use of static functions that are members of a class. But what might be the probable use of static functions that are not related to any class or defined globally. eg-
#include <iostream>
using namespace std;
static int func()
{
cout<<"This is a function";
}
int main()
{
/*Random code here*/
return 0;
}
This creates a function that's visible only inside that translation unit. A translation unit is basically that source file (after preprocessing, so what was in the headers it included plus what's directly in the file itself).
It's roughly equivalent to putting the function inside an anonymous namespace, but the anonymous namespace is generally considered preferable.
We can have anonymous namespaces (namespace with no name). They are directly usable in the same program and are used for declaring unique identifiers. It is said that it avoids making global static variable.My question is if it is not static then why default value is zero?
As these question has been asked before but it is not clear at all C++ anonymous namespace: Variables initialized to 0?
#include<iostream>
using namespace std;
namespace
{
int x; // Here x should have garbage value according to definition of anonymous namespace
}
int main()
{
cout << x << endl;// But x is throwing zero why?
}
The anonymous namespace doesn't really prevent names from becoming global names! In fact, a compiler may create object files which define the symbols as global symbols. However, the anonymous namespace basically hides these global names away with a name which can only be referred to from one translation unit.
The zero initialization applies to all objects with static storage duration. All variables at namespace level, including the anonymous namespace and function local static variable have static storage duration unless they are declared thread_local.
I think you incorrectly understand the phrase
It is said that it avoids making global static variable
or the phrase itself is confusing.
In this phrase word static means internal linkage. For example if you will write
namespace N // named namespace
{
static int x;
}
then variable x will have internal linkage. it will not be visible outside the compilation unit where it is defined. Or each module that will contain this definition will have a separate object with name x.
To achieve the same effect you could place its definition in an unnamed namespace. In this case according to the C++ 2011 Standard it will also have the internal linkage.
namespace // unnamed namespace
{
int x;
}
At the same time any object defined in a namespace has static storage duration. It means that it will be initialized. For fundamental scalar types the initialization is the zero initialization.
I understand that static function declarations are done at the top of .cpp files such that I can use it only within that file and compiler would not complain if there are functions in other files with the same name. Is there an equivalent for classes? That is, declaring a "private" class used only within that file.
First, the C++ specification does not refer to source code files.
The relevant unit here is a translation unit, also called a compilation unit, and in practical terms it consists of all the source code resulting from preprocessing of an implementation file.
So you can have internal linkage (a.k.a. static) functions in any kind of file. Although it doesn't make much practical sense to have them in a header file. Also, the placement in the code, whether first or last, does not matter.
An alternative to an internal linkage function like
static void foo() {}
is to place the function in an anonymous namespace, like
namespace {
void foo() {}
} // namespace <anon>
and you can do that also for a class.
Effectively this is equivalent to
namespace very_unique_autogenerated_name {
void foo() {}
}
// And in global namespace:
using namespace very_unique_autogenerated_name;
which means that you can refer to things in the anonymous namespace as if they were in the global namespace, and that you can have external linkage things there without their names colliding with other things in anonymous namespaces in other translation units.
XY problem? You can have classes with the same name in different files, unless you link them together. If your problem is that you have a name conflict, you can resolve that using namespaces:
//file1.cpp
namespace file1 {
class A { .. };
}
//file2.cpp
namespace file2 {
class A { .. }; //compiler won't complain
}
You can use unnamed namespaces for this:
namespace {
class A {};
}
There is more discussion at Unnamed/anonymous namespaces vs. static functions
If you want to put function definitions in header files, it appears there are three different solutions:
mark the function as inline
mark the function as static
put the function in an anonymous namespace
(Until recently, I wasn't even aware of #1.) So what are the differences to these solutions, and when I should I prefer which? I'm in header-only world, so I really need the definitions in the header files.
The static and unnamed namespace versions end up being the same: each Translation Unit will contain it's own version of the function, and that means that given a static function f, the pointer &f will be different in each translation unit, and the program will contain N different versions of f (more code in the binary).
This is not the right approach to provide a function in a header, it will provide N different (exactly equal) functions. If the function contains static locals then there will be N different static local variables...
EDIT: To make this more explicit: if what you want is to provide the definition of a function in a header without breaking the One Definition Rule, the right approach is to make the function inline.
As far as I know, only inline and template functions can be defined in header files.
static functions are deprecated, and functions defined in an unnamed namespace should be used instead (see 7.3.1.1 p2). When you define a function in an unnamed namespace in a header, then every source code including that header (directly or indirectly) will have an unique definition (see 7.3.1.1 p1). Therefore, functions should not be defined in the unnamed namespace in header files (only in source files).
The standard referenced are from the c++03 standard.
EDIT:
Next example demonstrates why functions and variables shouldn't be defined into unnamed namespace in headers :
ops.hpp contains:
#ifndef OPS_HPP
#define OPS_HPP
namespace
{
int a;
}
#endif
dk1.hpp contains:
#ifndef DK1_HPP
#define DK1_HPP
void setValue();
void printValue();
#endif
dk1.cpp contains:
#include "dk1.hpp"
#include "ops.hpp"
#include <iostream>
void setValue()
{
a=5;
}
void printValue()
{
std::cout<<a<<std::endl;
}
dk.cpp contains :
#include "dk1.hpp"
#include "ops.hpp"
#include <iostream>
int main()
{
// set and print a
setValue();
printValue();
// set and print it again
a = 22;
std::cout<<a<<std::endl;
// print it again
printValue();
}
Compile like this:
g++ -ansi -pedantic -Wall -Wextra dk.cpp dk1.cpp
and the output :
5
22
5
ops the variable a is different for the source file dk1.cpp and dk.cpp
static functions (equivalent to anonymous namespace) receive different copies for each TU. If the function is re-entrant this is basically identical (some compilers might have assembly-level differences) but if it isn't then it will have different static data for each TU. Inline functions are folded- that is, they have only one copy of static data for every TU.
You could consider wrapping the methods in a class instead of a namespace. Declare these methods as static and delete the constructor of the class to reinforce that this is not an object to be instantiated.
struct FooNamespace
{
FooNamespace() = delete;
static FooMethod1() {
...
}
static FooMethod2() {
...
}
};
You get the same general behavior as it belonging to a namespace with only a single implementation.
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)
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.