What are disadvantages of using static variables like in following code:
namespace XXX
{
static int i;
class YYY
{
static m_i;
};
}
Is using static variables only in .cpp (so they are invisible to other code) file OK?
It totally depends on what you need to do. There is no general aversion to using statics. Note that statics are essentially the singleton pattern, so all the pros/cons about singletons apply.
In terms of threads you have to pay attention since the same instance could be access by multiple threads at the same time. If you only need to read the data then you shouldn't have any problems. If you need to modify the data you have to worry about synchronization.
For code reuse and testing singeltons can often pose a problem. You can't for example recreate the object in a test, or have multiple run in parallel. In general when I use singletons/statics I try to ensure that one instance of the entire life of all tests, parallel executions, etc. is totally okay.
Invisible statics as you call them (visible only to the compilation unit) are a good idea. This helps you maintain synchronization between threads and manage them correctly. If they have global visibility then they can be modified at any time (well private variables can't, so they are also good).
Also note that atomic variables can be safely read/written from various threads. For simple counters this is often a good solution: using atomic increment. In C++0x you can use "atomic", previously use your OS/compiler function that does it. As with the singleton pattern, you can easily design classes where each function is synchronized so the singleton user doesn't have to worry about it. That is to say, statics aren't inherently thread-safe even when doing writing.
Various things allowed by C++ represent choices and compromises in software design. There is nothing inherently, absolutely evil about any of them (except perhaps throw specifications, which Prof. Stroustrop deems a broken facility ;-P).
Whether this particular code is a good choice in a particular situation depends on many factors. For example:
static:
In short, if you realise that namespaces and static just reduce identifier clashes, they've got all the other pros/cons associated with global variables....
Also you can have some problems with static class members while working with runtime shared libs. For example: if you have:
class A {
//...
static int staticInt;
//...
};
And you link this class to main executable AND to runtime shared lib, which is used by this executable (via dlopen) in several cases you can receive segmentation faults due to reinitialization of main executable's copy of static member by loaded shared lib. You can find more details concerning this issue here and there
For one it's not thread safe. You might want to consider the singleton pattern with some kind of locking to protect it.
One disadvantage you must be aware of is the so-called "static initialization order fiasco." Here is an example:
// foo.cpp
class foo {
public:
static bar m_bar;
};
bar foo::m_bar;
// baz.cpp
class baz {
public:
baz() {
/* some code */
foo::m_bar.someMethod();
}
};
baz g_baz; //TROUBLE!!
The C++ standard makes no guarantee about which will be initialized first of m_bar and g_baz. If you're lucky and m_bar gets initialized first, g_baz will be constructed without a hitch. If not, your program will likely segfault, or worse.
Replacing m_bar with a method returning a static pointer constructed on first use circumvents this problem (NB: it's still not thread-safe):
class foo {
public:
static bar &getBar() { if(!m_barinst) m_barinst = new bar; return *m_barinst; }
private:
static bar *m_barinst;
};
bar *foo::m_barinst = NULL;