I have been reading different articles on memory management in preparing for how I want my architecture to work, with my biggest worries on how the allocators will be used, created and handled throughout the code base. One of the issues is that my design always has the allocator(s) at a global scope, since I don't have a typical singleton design to contain the allocators, they have no real place to live. I would like to avoid using globals for this due to all the issues typical had with using globals.
This lead me to the design of having something such as
void* operator new(size_t size, uint32_t type)
{
return gAllocator.Alloc(size, type);
}
This would then lead to having just the new definition in a header file, with the declaration in a .cpp. This .cpp file would then have the gAllocator, only in the .cpp file (and can be accessed in place else except for the new call.
If my design would to be like this, would the gAllocator still be a global variable, if not, what type of variable would it be considered? What if it was in the scope of just a namespace?
It seems a plain global is just what you want. For review, in C++ a global (or singleton) should be a local static variable in an inline function.
class myAllocator {
public:
static myAllocator &getDefaultInstance() {
static myAllocator theInstance( parameters );
return theInstance;
}
};
This way, the object is initialized the first time it's used. If you use a typical header declaration + .cpp definition, the order of initialization with respect to other globals is undefined, with possible unpredictable consequences. (The "static initialization order fiasco.")
Related
I inherited a project from a former colleague, and I found these code snippets (and some similar ones in SO questions: can a c++ class include itself as an member and static member object of a class in the same class)
// Service.h
class Service
{
// ...
public:
static Service sInstance;
void Somememberfunc();
//...
};
// Service.cpp
#include "Service.h"
Service Service::sInstance;
void Service::Somememberfunc()
{
//...
}
// Main.cpp
#include "Service.h"
void Fun()
{
Service &instance = Service::sInstance;
//...
instance.Somememberfunc();
//...
}
However, I did not find any explanation on when to use this pattern. And what are the advantages and disadvantages?
Notice that the member is a static, so it's part of the class, not of instantiated objects. This is important, because otherwise you would be trying to make a recursive member (since the member is part of the object, it also contains the same member and so on...), but this is not the case here.
The best pattern to describe this is: global variable. The static member is initialized before main() and can be accessed from any part of the program by including the header file. This is very convenient while implementing but becomes harder to handle the more complex the program gets and the longer you have to maintain it, so the general idea is to avoid this. Also, because there is no way to control the order of initialization, dependencies between different global variables can cause problems during startup.
Static member is roughly a global variable in the scope of the class.
Static members have also the advantage of visibility access (public/protected/private) to restreint its usage (file scope might be an alternative).
That member might be of type of the class.
Global are "easy" to (mis)use, as they don't require to think about architecture.
BUT (mutable) global are mostly discouraged as harder to reason about.
Acceptable usages IMO are for constants:
as for a matrix class, the null matrix, the diagonal one matrix.
for Temperature class, some specific value (absolute 0 (O Kelvin), temperature of water transformation(0 Celsius, 100 Celsius), ...)
in general NullObject, Default, ...
Singleton pattern. For example, you can use it to store your app configurations. And then you can easily access configurations anywhere(globally) within your app.
This is often used in the singleton design pattern
Visit https://en.wikipedia.org/wiki/Singleton_pattern
Say you have a certain class in which each instance of it needs to access the exact same set of data. It is more efficient to declare the data outside the class rather than have each instance make its own one, but doesn't this breach the 'no globals' rule?
Example code:
Foo.h
class Foo{
Foo();
void someFunction();
};
Foo.cpp
#include "Foo.h"
//surely ok since it's only global to the class's .cpp?
const int g_data[length] = {
//contains some data
};
Foo::someFunction(){
//do something involving g_data ..
}
..rather than making 'g_data' a member variable. Or is there some other way which avoids creating a global?
Use the modifier static which modifies the declaration of a class member so that is shared among all class instances. An example:
class A {
int length = 10;
static int g_data[length]; //Inside the class
}
And then you can access it like this:
int main(void) {
std::cout << "For example: " << A::g_data[2] << std::endl;
}
You can find more on this matter here
That's what a static member is for.
Thus you will have in your declaration :
class Foo{
Foo();
void someFunction();
static int const sharedData[length];
};
And somewhere in your cpp file :
int const Foo::sharedData[length] = { /* Your data */ };
Summarily, yes - your "global" is probably ok (though it'd be better in an anonymous namespace, and there are a few considerations).
Details: lots of answers recommending a static class member, and that is often a good way to go, but do keep in mind that:
a static class member must be listed in the class definition, so in your case it'll be in Foo.h, and any client code that includes that header is likely to want to recompile if you edit the static member in any way even if it's private and of no possible direct relevance to them (this is most important for classes in low-level libraries with diverse client code - enterprise libraries and those shared across the internet and used by large client apps)
with a static class member, code in the header has the option of using it (in which case a recompile will be necessary and appropriate if the static member changes)
if you put the data in the .cpp file, it's best in an anonymous namespace so it doesn't have external linkage (no other objects see it or can link to it), though you have no way to encapsulate it to protect it from access by other functions later in the .cpp's translation unit (whereas a non-public static class member has such protection)
What you really want is data belonging to the type, not to an instance of that type. Fortunately, in C++ there is an instrument doing exactly that — static class members.
If you want to avoid the global and have a more object-oriented solution, take a look at the Flyweight pattern. The Boost Flyweight library has some helper infrastructure and provides a decent explanation of the concept.
Since you are talking about efficiency, it may or not be a good idea to use such an approach, depending on your actual goal. Flyweights are more about saving memory and introduce an additional layer of indirection which may impact runtime performance. The externally stored state may impact compiler optimizations, especially inlining and reduce data locality which prevents efficient caching. On the other hand, some operations which like assignment or copying can be considerably faster because there is only the pointer to the shared state that needs to be copied (plus the non-shared state, but this has to be copied anyway). As always when it comes to efficiency / performance, make sure you measure your code to compare what suits your requirements.
I frequently have to write c/c++ programs with 10+ source files where a handful of variables need to be shared between functions in all the files. I have read before that it is generally good practice to avoid using global variables with extern. However, if it is completely necessary to use global variables, this link provides a good strategy. Lately, I have been toying with the strategy of wrapping up all my variables in a struct or a class and passing this struct around to different functions. I was wondering which way people consider to be cleaner and if there are any better alternatives.
EDIT: I realize strategies may be different in the two languages. I am interested in strategies that apply to only one language or both.
Pass around a class/struct of "context" data instead of global variables. You will be suprised how often a global variable becomes no longer global, with different modules wanting to use different values for it at the same time.
The better alternative to globals is to not use globals.
Don't try to sweep them under the rug using a struct or a namespace or a singleton or some other silly thing whose only purpose is to hide the fact that you're using globals.
Just don't ever create one. Ever.
It will force you to think of ownership and lifetime and dependencies and responsibility. You know, grown-up things.
And then, when you're comfortable writing global-free code, you can start violating all those rules.
Because that's what rules are for: to be followed, and to be broken.
Does it REALLY need to be global?
This is the first question you should always ask, is this variable used GLOBALLY e.g. in all contexts. The answer is almost certainly... no it's not.
Consider Context
Is the variable global state, or is it context? Global state is usually rare, context on the other hand is quite common. If it's global state consider wrapping in a singleton so you can manage the how of interaction with your globals. Using Atomic<> is probably not a bad idea, you should at least consider synchronization.
If it is context then it should be passed explicitly in a structure or class, as the data is explicitly relevant to that context an no-other. Passing context explicitly may seem like a burden but it makes it very clear where the context is coming from rather than just referencing random variables out of the ether.
What is the Scope?
It may seem odd to say that globals are scoped, but any global declared in a single file may be declared static and thus unlinkable from any other file. This means you can restrict who has access to the global state in a given scope. This allows you to prevent people from randomly tweaking variables.
My take in C++
I found it a good practice in C++ anyway to limit the scope of my global variables with a namespace. That way you can eliminate any ambiguity between your 10+ source files.
For example:
namespace ObjectGlobalVars {
//Put all of your global variables here
int myvariable = 0;
}
//And then later on you can reference them like
ObjectGlobalVars::myvariable++;
In c++
Having global variables lying around here and there, is an example of bad code.
If you want to share things on a global scale, then group them up and follow the singleton pattern.
Example:
class Singleton
{
private:
int mData;
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
int GetData()
{
return mData;
}
private:
Singleton() {};
Singleton(Singleton const&);
void operator=(Singleton const&);
};
Advantages:
Only 1 global variable. The instance of our singleton.
You can include mutex / semaphore mechanisms inside the singleton, for thread-safe access of it's members.
Restricts the access of it's members helping you avoid logical and synchronization flaws.
Disadvantages:
Harder to implement. - If it's your first time -
In c
You should avoid declaring global variables, pass them in structs instead.
For instance:
struct MyData
{
int a;
int b;
};
void bar(struct MyData* data)
{
data->b = 2;
}
void foo()
{
struct MyData mdata;
mdata.a = 1;
bar( &mdata );
}
To sum things up
Having global variables lying around should be avoided as much as possible, in both languages.
So I recently found some source code which used a particular technique(idiom?) I hadn't seen before; to put it simply; instead of using a static variable for the class in question, it used a local variable inside the classes source file.
myclass.h
class myclass {
//static int myint;
public:
myclass();
~myclass();
int count();
};
myclass.cpp
#include "myclass.h"
int myint = 0;
myclass::myclass() {
myint++;
}
myclass::~myclass() {
myint--;
}
int myclass::count() {
return myint;
}
main.cpp
#include "myclass.h"
#include <iostream>
int main() {
myclass aclass;
myclass theclass;
std::cout << theclass.count(); //outputs 2
return 0;
}
My question is, why would someone take this approach over using a static variable?
My take on it is that, since ideally the variable would only be known to the myclass class (private static), and inheritance is not of importance at all (in this case), this could stop others knowing about this variable. But that is the only advantage I can see; not sure if that would warrant it.
The same question goes for (static / non - static) member functions that are private; when inheritance is not important.
EDIT: After reading around, I'm going to make a stab that it is because some people still use C programming style...
It doesn't really matter whether you use a static member variable or a global variable or a locally declared static variable; the only important thing is that the object has to have static storage duration. Beyond that, the choice is mostly based on personal preference or coding style guidelines.
Unfortunately, this code is basically wrong. While myint is "hidden" and only directly accessible from within myclass.cpp, it still has external linkage. This means that it is accessible from other translation units (by using extern int myint in those other translation units) and its definition can conflict with other definitions of myint in other translation units.
To correct this, it should either be declared static (giving it internal linkage) or, preferably, it should be declared in an unnamed namespace,
namespace {
int myint;
}
(an object in an unnamed namespace may still have external linkage, but it is uniquely named so it cannot be used by its name from outside of the translation unit in which it is compiled.)
In your example the variable is not static and is technically visible outside the compilation unit if properly declared. If this is not intentional it can be a source of problems if another compilation unit uses the same trick on a variable with the same name (to fix this see James McNellis answer).
Assuming a properly declared static (e.g. using the unnamed namespace approach) this technique can be better than a class static because it hides completely the variable from class users. This means that if you need to add or modify that variable the clients don't even need to be recompiled (you just need to recompile the implementation .cpp file and then to relink the program). This can be a big difference if your class is used everywhere in a big project (compile just one file instead of recompiling the whole world because of a change in an internal detail).
Also if the static variable is not an int but something more complex (e.g. a templated class instance) then putting the variable in the class as a static requires to expose much more data to clients, introducing not needed dependencies.
Sometimes this unwanted dependency problem is considered so important that you can find implementation of the "compiler firewall" idiom. This hiding is sort of a partial and light version of it.
My question is, why would someone take this approach over using a static variable?
it makes sense if you have something to hide -- an int is not worth usually hiding, but a large library is. an author may also prefer to hide implementation details from clients in some cases.
regarding static functions -- i'll typically hide them if they are just free helpers, and really don't belong in, or are required to be a part of the class interface.
generally, i'll put it in the class interface simply for organizational purposes.
In C++, say you want to declare a global variable to be used by many. How do you do it?
I commonly use declare and define in cpp file, and then use extern in other cpp file (and not headers).
I don't like this approach, and I am considering something along these lines:
In a header file:
some_file.h
Class MYGlobalClass
{
};
MyGlobalClass& MyGlobalClassInstance()
{
static MYGlobalClass instance;
return instance;
}
Edit
Consider in the following contexts:
can be used in multi-threaded applications
namespace pollution
may NOT necessery be a singleton, as many instances of this might be created
What are your thoughts, suggestions, new ideas?
The best advice is probably "try to avoid globals". People don't need global variables as often as they think. Usually it turns out that "passing everything as arguments to constructors" isn't quite as much work as people think when they hear the suggestion. It also tends to lead to cleaner code with fewer, and more explicit, dependencies.
I'm not aware of any "correct" way to declare globals in C++. The way you do it now works fine, but the order of initialization is unspecified, so if there are any dependencies between your globals, you're in trouble.
A function returning a static instance more or less solves that problem, but isn't thread safe.
And a singleton is just a terrible idea. It doesn't solve your problem, but adds additional constraints to your code, which weren't actually necessary, and will most likely come back and bite you later.
Declare as extern in one header file included by "many" and define it in one *.cpp file
Declare it in one header file (using extern), and define it in one .cpp (or whatever other extension) file. You may use a function and return a reference to a static variable like you showed to circumvent problems with construction order relative to other such namespace scope variables in other .cpp files. But remember that won't protect you from destruction order problems - which is in the exact reverse order from construction (these things are called "static initialization order fiasco". If you use a function like yours and put it into headers, make it inline to make the redefinition of the function valid when it is included into multiple .cpp files (logically, the function is still only apparent once, because the static in it will only exist once, not separately for each file it is included into). Alternatively just declare it in a header but define it in one .cpp file (but then, remove the inline from it!).
inline A& getA() { static A a; return a; }
The potential problems with destruction order can be circumvented by using new:
inline A& getA() { static A *a = new A; return *a; }
The destructor of it, however, will never be called then. If you need thread safety, you should add a mutex that protects against multiple accesses. boost.thread probably has something for that.
Your idea of a static inside the accessor function is significantly different from a global variable. The difference is when it is constructed, and is most likely to be a major problem with multiple threads. What if two threads call MyGlobalClassInstance at the same time? Depending on the environment, but I suspect this is typical of most C++ compilers, you will potentially get two calls to the constructor of MyGlobalClass running at the same time, addressing the same area of memory.
If you're single-threaded, it's less likely to be a problem.
If you declare the instance as a normal static member or as a normal global variable in the source file, you'll probably have an easier time, because the constructor will be called before main executes, before you have a chance to start other threads.
declare and define in cpp file
Keep the extern-ed declaration in a header. Define it only once in an implementation file.
You are close. Use a namespace instead for global variables.
namespace myns {
int foo = 0;
}
Now, if it is a class object, you are looking at the Singletion pattern. In fact, your sample code reflects a Singleton design. However, if you are going to define the function in the header, make it inline -- ODR violation otherwise.
It it's truly a global variable that could theoretically be accessed externally by any module, you should put the extern declaration in the header file:
// MyClass.h
class MyClass { ... };
extern MyClass myGlobalInstance;
// MyClass.cpp
MyClass myGlobalInstance;
If it's just a global object that should really only be accessed by a single module, limit its scope by either making it a private (or protected) static class variable, a static function variable (if it's only needed by one function), or in an anonymous namespace:
Option 1:
// MyClass.h
class MyClass
{
private: // or protected, if you want it accessible by subclasses
static MyClass myGlobalInstance;
};
Option 2:
// MyClass.cpp
void someFunction()
{
// it's global, but only accessible inside this function
static MyClass myGlobalInstance;
...
}
Option 3:
// MyClass.cpp
namespace
{
MyClass myGlobalInstance;
}
// it's now only accessible in this file
extern MyGlobalClass MyGlobalClassInstance;
Edit: Not static >.<
Why not use good old singleton pattern?