Recently a fellow worker showed to me a code like this:
void SomeClass::function()
{
static bool init = false;
if (!init)
{
// hundreds of lines of ugly code
}
init = true;
}
He wants to check if SomeClass is initialized in order to execute some piece of code once per Someclass instance but the fact is that only one instance of SomeClass will exist in all the lifetime of the program.
His question were about the init static variable, about when it's initialized. I've answered that the initialization occurs once, so the value will be false at first call and true the rest of its lifetime. After answering I've added that such use of static variables is bad practice but I haven't been able to explain why.
The reasons that I've been thinking so far are the following:
The behaviour of static bool init into SomeClass::function could be achieved with a non-static member variable.
Other functions in SomeClass couldn't check the static bool init value because it's visibility is limited to the void SomeClass::function() scope.
The static variables aren't OOPish because they define a global state instead of a object state.
This reasons looks poor, unclever and not very concrete to me so I'm asking for more reasons to explain why the use of static variables in function and member-function space are a bad practice.
Thanks!
This is certainly a rare occurrence, at least, in good quality code, because of the narrow case for which it's appropriate. What this basically does is a just-in-time initialization of a global state (to deliver some global functionality). A typical example of this is having a random number generator function that seeds the generator at the first call to it. Another typical use of this is a function that returns the instance of a singleton, initialized on the first call. But other use-case examples are few and far between.
In general terms, global state is not desirable, and having objects that contain self-sufficient states is preferred (for modularity, etc.). But if you need global state (and sometimes you do), you have to implement it somehow. If you need any kind of non-trivial global state, then you should probably go with a singleton class, and one of the preferred ways to deliver that application-wide single instance is through a function that delivers a reference to a local static instance initialized on the first call. If the global state needed is a bit more trivial, then doing the scheme with the local static bool flag is certainly an acceptable way to do it. In other words, I see no fundamental problem with employing that method, but I would naturally question its motivations (requiring a global state) if presented with such code.
As is always the case for global data, multi-threading will cause some problems with a simplistic implementation like this one. Naive introductions of global state are never going to be inherently thread-safe, and this case is no exception, you'd have to take measures to address that specific problem. And that is part of the reasons why global states are not desirable.
The behaviour of static bool init into SomeClass::function could be achieved with a non-static member variable.
If there is an alternative to achieve the same behavior, then the two alternatives have to be judged on the technical issues (like thread-safety). But in this case, the required behavior is the questionable thing, more so than the implementation details, and the existence of alternative implementations doesn't change that.
Second, I don't see how you can replace a just-in-time initialization of a global state by anything that is based on a non-static data member (a static data member, maybe). And even if you can, it would be wasteful (require per-object storage for a one-time-per-program-execution thing), and on that ground alone, wouldn't make it a better alternative.
Other functions in SomeClass couldn't check the static bool init value because it's visibility is limited to the void SomeClass::function() scope.
I would generally put that in the "Pro" column (as in Pro/Con). This is a good thing. This is information hiding or encapsulation. If you can hide away things that shouldn't be a concern to others, then great! But if there are other functions that would need to know that the global state has already been initialized or not, then you probably need something more along the lines of a singleton class.
The static variables aren't OOPish because they define a global state instead of a object state.
OOPish or not, who cares? But yes, the global state is the concern here. Not so much the use of a local static variable to implement its initialization. Global states, especially mutable global states, are bad in general and should never be abused. They hinder modularity (modules are less self-sufficient if they rely on global states), they introduce multi-threading concerns since they are inherently shared data, they make any function that use them non-reentrant (non-pure), they make debugging difficult, etc... the list goes on. But most of these issues are not tied to how you implement it. On the other hand, using a local static variable is a good way to solve the static-initialization-order-fiasco, so, they are good for that reason, one less problem to worry about when introducing a (well-justified) global state into your code.
Think multi-threading. This type of code is problematic when function() can be called concurrently by multiple threads. Without locking, you're open to race conditions; with locking, concurrency can suffer for no real gain.
Global state is probably the worst problem here. Other functions don't have to be concerned with it, so it's not an issue. The fact that it can be achieved without static variable essentially means you made some form of a singleton. Which of course introduces all problems that singleton has, like being totally unsuitable for multithreaded environment, for one.
Adding to what others said, you can't have multiple objects of this class at the same time, or at least would they not behave as expected. The first instance would set the static variable and do the initialization. The ones created later though would not have their own version of init but share it with all other instances. Since the first instance set it to true, all following won't do any initialization, which is most probably not what you want.
Related
I know that C++ also allows to create global objects of class and struct.
#include <iostream>
using std::cout;
class Test
{
public:
void fun()
{
cout<<"a= "<<a;
}
private:
int a=9;
};
Test t; // global object
int main()
{
t.fun();
return 0;
}
When & where should i use global objects? Is there any specific use of global objects? Please help me.
The short answer is there is no need.
The long answer is that it can sometimes be convenient. Unfortunately convenience is subjective, and what one finds to convenient another might find to be too lenient.
Global objects have issues (among which muddying data flows in the code and access synchronization), but sometimes one might find it convenient nonetheless to use one because it makes something easier. It can indeed remain easier, or it can prove a maintenance burden, but that only the future can tell...
... If you can avoid global objects, in general you should be better off. In practice, though, you will rarely encounter issues before programming at scale; for toy examples and students' projects there is rarely an issue, which is why beginners fail to understand why more seasoned developers avoid them like the plague.
In a complex project, you shouldn't. You should always be within a namespace if you plan to use you're assembly in other projects.
An example of something that might be that high in scope is an operator overload or an interface that you define which will be used many times.
Good practice...organize your project to use descriptive and intuitive namespaces.
Global is really only useful in simple project that simple don't use namespaces.
The question is malposed: is there a need for if wile and do, since we can do all with just for ?
The technical answer is "no, there is no need: the fact we can do without proves it". But a little more pragmatism show us that reducing every control flow into a single keywork makes code harder to track and follow. So it is technically possible but not always convenient.
Now: can we do without global objects?
A first non-answer is "yes, with singletons". But a singleton is a static object obtained through a function. They are not that conceptually different if not for a design flaw (known as "static initialization order fiasco") due to C++ not specifying global initialization object order essentially to allow multiple translation unit to coexist in a same linked executable. Singleton allow to circumvent that problem, but are essentially a workaround to allow global "things" to exist.
The existence of that flaw (and the singleton technique) is wat makes many "teachers" to draw some "moral" suasion like "never use global objects, or the flame of hell will burn your ass-hair". But that soon do std::cout << "hello world" and immediately loose ALL their credibility.
The point is that without "globals" everything is "scope local" and there is no "dynamic scope" in C++: if funcA calls funcB, funcB cannot see funcA locals, hence the only way to access things across scopes is parameter passing of reference or pointers.
In context which are mostly "functional", the missing of "dynamic scopes" is compensated by "lamba captures", and everything else will go as paramenter.
In context which are mostly "procedural", the need of a "state" that survives scopes and can be modified while going in and out is more suited for global objects. And that's the reason cout is that. It represent a resource theat pre-exist and post-exist the program, whose state evolves across various calls. If there is no global way to access cout, it should be initialized in main, an passed as a reference parameter to whatever function call: even the one that have no output to give, since they may call themselves something else that has output to give.
In fact you can think to global object as "implicit parameters passed to every function".
You can warp in global functions but -if functions themselves can be objects and object themselves can be functional- why saying global objects are bad and global functions can be right?
The actual only reason, in fact, turns out to be the static initialization order fiasco
I would say that global variables are needed for backwards compatibility with c. That is for sure, and this is the only hard reason I see. Since classes and structs are essentially the same, it probably didn't make much sense in forbidding only one.
I don't know any patterns or use-cases that are universally accepted as a good practice, that would make use of global objects. Usually global objects, sooner or later, lead to mess if not interacted with properly. They hide data flow and relationships. It is extremely easily to trip over it.
Still, I have seen some libraries exposing some objects as globals. Usually things that contain some static data. But there are other cases too, notable example being standard library's std::cout and family.
I won't judge if it's good or bad approach. This is too subjective IMO. You could probably use singletons, but one might argue, you can work on a global object under a contract etc. etc.
I'm still learning C++. I have one problem. Lets say that your project has global object which always exists e.g ApiManager and all other modules have access to it (by #include). For now I'm doing it by:
Header:
class ApiManager : public QObject
{
Q_OBJECT
public:
explicit ApiManager(QObject *parent = 0);
signals:
public slots:
};
extern ApiManager apiMng;
Source:
ApiManager apiMng;
The problem is that other objects need to have access when initialized too and I noticed that C++ global objects are created alphabetically. I'm wondering how do you deal with it? Exists some trick for this? For example in Free Pascal world each class module has initialization and finalization sections:
Type
TApiManager = class
end;
var ApiMng: TApiManager;
initialization
ApiMng := TApiManager.Create;
finalization
ApiMng.Free;
... and initialization order of project modules can be sorted in project source in uses clause (like #include in C++). I know that there is a lot of ways to do this (for example initialize everything in main.cpp with custom order) but want to know what is a "good habit" in C++ world
Edit: Solved by Q_GLOBAL_STATIC (introduced in Qt 5.1 but work for Qt 4.8 too) but still have two issues:
Still don't know how to manage constructor orders (and where to initialize it). Because global objects created by Q_GLOBAL_STATIC are not created at application startup. They are created on first usage. So I need to "touch" these object somewhere (in main.cpp?) with my custom order.
Documentation is saying that Q_GLOBAL_STATIC must be called in body .cpp file, not in header. But then other classes do not see this object. So I created static function which expose reference to this object:
.cpp:
Q_GLOBAL_STATIC(ApiManager, apiMng)
ApiManager *ApiManager::instance()
{
return apiMng();
}
But from this topic: http://qt-project.org/forums/viewthread/13977 Q_GLOBAL_STATIC should expose instance automatically, but it doesn't
They are not initialized in alphabetical order, and the initialization order among the translation units are undefined as nothing is guaranteed by the standard about it.
Why global variables are evil
Global variables should be avoided for several reasons, but the primary reason is because they increase your program’s complexity immensely. For example, say you were examining a program and you wanted to know what a variable named g_nValue was used for. Because g_nValue is a global, and globals can be used anywhere in the entire program, you’d have to examine every single line of every single file! In a computer program with hundreds of files and millions of lines of code, you can imagine how long this would take!
Second, global variables are dangerous because their values can be changed by any function that is called, and there is no easy way for the programmer to know that this will happen.
Why Global Variables Should Be Avoided When Unnecessary
Non-locality -- Source code is easiest to understand when the scope of its individual elements are limited. Global variables can be read or modified by any part of the program, making it difficult to remember or reason about every possible use.
No Access Control or Constraint Checking -- A global variable can be get or set by any part of the program, and any rules regarding its use can be easily broken or forgotten. (In other words, get/set accessors are generally preferable over direct data access, and this is even more so for global data.) By extension, the lack of access control greatly hinders achieving security in situations where you may wish to run untrusted code (such as working with 3rd party plugins).
Implicit coupling -- A program with many global variables often has tight couplings between some of those variables, and couplings between variables and functions. Grouping coupled items into cohesive units usually leads to better programs.
Concurrency issues -- if globals can be accessed by multiple threads of execution, synchronization is necessary (and too-often neglected). When dynamically linking modules with globals, the composed system might not be thread-safe even if the two independent modules tested in dozens of different contexts were safe.
Namespace pollution -- Global names are available everywhere. You may unknowingly end up using a global when you think you are using a local (by misspelling or forgetting to declare the local) or vice versa. Also, if you ever have to link together modules that have the same global variable names, if you are lucky, you will get linking errors. If you are unlucky, the linker will simply treat all uses of the same name as the same object.
Memory allocation issues -- Some environments have memory allocation schemes that make allocation of globals tricky. This is especially true in languages where "constructors" have side-effects other than allocation (because, in that case, you can express unsafe situations where two globals mutually depend on one another). Also, when dynamically linking modules, it can be unclear whether different libraries have their own instances of globals or whether the globals are shared.
Testing and Confinement - source that utilizes globals is somewhat more difficult to test because one cannot readily set up a 'clean' environment between runs. More generally, source that utilizes global services of any sort (e.g. reading and writing files or databases) that aren't explicitly provided to that source is difficult to test for the same reason. For communicating systems, the ability to test system invariants may require running more than one 'copy' of a system simultaneously, which is greatly hindered by any use of shared services - including global memory - that are not provided for sharing as part of the test.
In general, please avoid global variables as a rule of thumb. If you do need to have them, please use Q_GLOBAL_STATIC.
Creates a global and static object of type QGlobalStatic, of name VariableName and that behaves as a pointer to Type. The object created by Q_GLOBAL_STATIC initializes itself on the first use, which means that it will not increase the application or the library's load time. Additionally, the object is initialized in a thread-safe manner on all platforms.
You can also use Q_GLOBAL_STATIC_WITH_ARGS. Here you can find some inline highlight from the documentation:
Creates a global and static object of type QGlobalStatic, of name VariableName, initialized by the arguments Arguments and that behaves as a pointer to Type. The object created by Q_GLOBAL_STATIC_WITH_ARGS initializes itself on the first use, which means that it will not increase the application or the library's load time. Additionally, the object is initialized in a thread-safe manner on all platforms.
Some people also tend to create a function for wrapping them, but they do not reduce the complexity significantly, and they eventually either forget to make those functions thread-safe, or they put more complexity in. Forget about doing that as well when you can.
The initialization order of global objects is only defined within a translation unit (there it is top to bottom). There is no guarantee between translation units. The typical work-around is to wrap the object into a function and return a reference to a local object:
ApiManager& apiMng() {
static ApiManager rc;
return rc;
}
The local object is initialized the first time the function is called (and, when using C++11 also in a thread-safe fashion). This way, the order of construction of globally accessed objects can be ordered in a useful way.
That said, don't use global objects. They are causing more harm than good.
Good habit in C++ world would be to avoid global objects at all costs - the more localized is the object the better it is.
If you absolutely have to have global object, I think the best would be to initialize objects in custom order in main - to be explicit about initialization order. Fact that you are using qt is one more argument towards initializing in main - you probably would want to initialize QApplication (which requires argc and argv as input arguments) prior to any other QObject.
I've been reading a lot about why global variables are bad and why they should not be used. And yet most of the commonly used programming languages support globals in some way.
So my question is what is the reason global variables are still needed, do they offer some unique and irreplaceable advantage that cannot be implemented alternatively? Are there any benefits to global addressing compared to user specified custom indirection to retrieve an object out of its local scope?
As far as I understand, in modern programming languages, global addressing comes with the same performance penalty as calculating every offset from a memory address, whether it is an offset from the beginning of the "global" user memory or an offset from a this or any other pointer. So in terms of performance, the user can fake globals in the narrow cases they are needed using common pointer indirection without losing performance to real global variables. So what else? Are global variables really needed?
Global variables aren't generally bad because of their performance, they're bad because in significantly sized programs, they make it hard to encapsulate everything - there's information "leakage" which can often make it very difficult to figure out what's going on.
Basically the scope of your variables should be only what's required for your code to both work and be relatively easy to understand, and no more. Having global variables in a program which prints out the twelve-times tables is manageable, having them in a multi-million line accounting program is not so good.
I think this is another subject similar to goto - it's a "religious thing".
There is a lot of ways to "work around" globals, but if you are still accessing the same bit of memory in various places in the code you may have a problem.
Global variables are useful for some things, but should definitely be used "with care" (more so than goto, because the scope of misuse is greater).
There are two things that make global variables a problem:
1. It's hard to understand what is being done to the variable.
2. In a multithreaded environment, if a global is written from one thread and read by any other thread, you need synchronisation of some sort.
But there are times when globals are very useful. Having a config variable that holds all your configuration values that came from the config file of the application, for example. The alternative is to store it in some object that gets passed from one function to another, and it's just extra work that doesn't give any benefit. In particular if the config variables are read-only.
As a whole, however, I would suggest avoiding globals.
Global variables imply global state. This makes it impossible to store overlapping state that is local to a given part or function in your program.
For example, let stay we store the credentials of a given user in global variables which are used throughout our program. It will now be a lot more difficult to upgrade our program to allow multiple users at the same time. Had we just passed a user's state as a parameter, to our functions, we would have had a lot less problems upgrading to multiple users.
my question is what is the reason global variables are still needed,
Sometimes you need to access the same data from a lot of different functions. This is when you need globals.
For instance, I am working on a piece of code right now, that looks like this:
static runtime_thread *t0;
void
queue_thread (runtime_thread *newt)
{
t0 = newt;
do_something_else ();
}
void
kill_and_replace_thread (runtime_thread *newt)
{
t0->status = dead;
t0 = newt;
t0->status = runnable;
do_something_else ();
}
Note: Take the above as some sort of mixed C and pseudocode, to give you an idea of where a global is actually useful.
Static Global is almost mandatory when writing any cross platform library. These Global Variables are static so that they stay within the translation unit. There are few if any cross platform libraries that does not use static global variables because they have to hide their platform specific implementation to the user. These platform specific implementations are held in static global variables. Of course, if they use an opaque pointer and require the platform specific implementation to be held in such a structure, they could make a cross platform library without any static global. However, such an object needs to be passed to all functions within such a library. Therefore, you have a pass this opaque pointer everywhere, or make static global variables.
There's also the identifier limit issue. Compilers (especially older ones) have a limit to the number of identifiers they could handle within a scope. Many operating systems still use tons of #define instead of enumerations because their old compilers cannot handle the enumeration constants that bloat their identifiers. A proper rewrite of the header files could solve some of these.
Global variables are considered when you want to use them in every function including main. Also remember that if you initialize a variable globally, its initial value will be same in every function, however you can reinitialize it inside a function to use a different value for that variable in that function. In this way you don't have to declare the same variable again and again in each function. But yes they can cause trouble at times.
List item
Global names are available everywhere. You may unknowingly end up using a global when you think you are using a local
And if you make a mistake while declaring a global variable, then you'll have to apply the changes to the whole program like if you accidentally declared it to be int instead of float
In a C++ multi-threaded application with many classes, i am trying to find out what are the methods to define a global variable
C style, define it as global in any one source file, define it as extern in a header which is included in the classes that access this variable.
Write a Singleton class, which contains these global variables and exposes set/get methods to write to the variable.
By second method one can control multi-threaded access via locks in a centralized manner rather than the first approach.
Are there more and better ways?
First of all try to avoid global variables as much as you can. If you just need to do it (by example this is the case with cin, cout and cerr) your second method is definitely the best (and more natural) way of doing it.
If the scope of your "global variable" can be narrowed down (which is typically the case - how many variables are truly global?) then you can make it a private static class member in the appropriate owning class. If your other classes need to see it (or less likely, update it), provide get/put accessors.
I would definitely go with the Singleton class. It's the best way to handle "global" variables in a multithreaded OOP environment.
If you must use a global variable (and why are you using one?) I recommend the second way you described. The first way is the way you can run into all kinds of namespace problems.
This probleam can be solved with an alternatieve method very easily.
C++ resolves this problem very easily by its new operator :: called scope resolution operator. The syntax is as follows
:: variable-name;
This operator allows access the global version of a vriable.
One tends to prefer the second method, because it seems to give you a better control but it may not turn out very useful in some scenarios.
First, In my understanding of philosophy of OOP, I do not consider objects as collections of bunch of data, but entities in terms of which, you can represent real world problems. So I do not consider it a good idea to to have a class to store random data. Especially when the data members are largely unrelated.
Second, If you are thinking of having a central control eg. having a single mutex to access all the data members, this is not going to work out very well for unrelated data members. You are going to block a lot of threads unnecessarily while the data they want is not exactly the one which is being currently protected by the lock.
So it may seem strange, but I would prefer the first method.
It depends on the problem at hand.
C-style globals have the advantage of simplicity, no need for Singleton::instance() call. However, Singleton::instance() allows you to initialize your global state on the first call.
To get the best of both worlds use C-style globals initialized using Schwarz Counter method. http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter
You can define a value object that wraps a single implementation with the handle/body idiom.
Also review "Modern C++ Design" by Alexandrescu for discussion about the difficulties of implementing singleton in MT environments and how to go about addressing them.
Not to kick a dead horse but, as mentioned, avoiding globals is the best solution. Some reasons are listed here. If a global variable is a must you might want to consider providing a function to access it from to avoid the so called 'global initialization fiasco'.
I have read multiple articles about why singletons are bad.
I know it has few uses like logging but what about initalizing and deinitializing.
Are there any problems doing that?
I have a scripting engine that I need to bind on startup to a library.
Libraries don't have main() so what should I use?
Regular functions or a Singleton.
Can this object be copied somehow:
class
{
public:
static void initialize();
static void deinitialize();
} bootstrap;
If not why do people hide the copy ctor, assignment operator and the ctor?
Libraries in C++ have a much simpler way to perform initialization and cleanup. It's the exact same way you'd do it for anything else. RAII.
Wrap everything that needs to be initialized in a class, and perform its initialization in the constructor. Voila, problems solved.
All the usual problems with singletons still apply:
You are going to need more than one instance, even if you hadn't planned for it. If nothing else, you'll want it when unit-testing. Each test should initialize the library from scratch so that it runs in a clean environment. That's hard to do with a singleton approach.
You're screwed as soon as these singletons start referencing each others. Because the actual initialization order isn't visible, you quickly end up with a bunch of circular references resulting in accessing uninitialized singletons or stack overflows or deadlocks or other fun errors which could have been caught at compile-time if you hadn't been obsessed with making everything global.
Multithreading. It's usually a bad idea to force all threads to share the same instance of a class, becaus it forces that class to lock and synchronize everything, which costs a lot of performance, and may lead to deadlocks.
Spaghetti code. You're hiding your code's dependencies every time you use a singleton or a global. It is no longer clear which objects a function depends on, because not all of them are visible as parameters. And because you don't need to add them as parameters, you easily end up adding far more dependencies than necessary. Which is why singletons are almost impossible to remove once you have them.
A singleton's purpose is to have only ONE instance of a certain class in your system.
The C'tor, D'tor and CC'tor are hidden, in order to have a single access point for receiving the only existing instance.
Usually the instance is static (could be allocated on the heap too) and private, and there's a static method (usually called GetInstance) which returns a reference to this instance.
The question you should ask yourself when deciding whether to have a singleton is : Do I really need to enforce having one object of this class?
There's also the inheritance problem - it can make things complicated if you are planning to inherit from a singleton.
Another problem is How to kill a singleton (the web is filled with articles about this issue)
In some cases it's better to have your private data held statically rather than having a singleton, all depends on the domain.
Note though, that if you're multi-threaded, static variables can give you a pain in the XXX...
So you should analyse your problem carefully before deciding on the design pattern you're going to use...
In your case, I don't think you need a singleton because you want the libraries to be initialized at the beginning, but it has nothing to do with enforcing having only one instance of your class. You could just hold a static flag (static bool Initialized) if all you want is to ensure initializing it only once.
Calling a method once is not reason enough to have a singleton.
It's a good practice to provide an interface for your libraries so that multiple modules (or threads) can use them simultaneously. If you really need to run some code when modules are loaded then use singletons to init parts that must be init once.
count the number of singletons in your design, and call this number 's'
count the number of threads in your design, and call this number 't'
now, raise t to the s-th power; this is roughly the number of hairs you are likely to lose while debugging the resulting code.
(I personally have run afoul of code that has over 50 singletons with 10 different threads all racing to get to .getInstance() first)