473,385 Members | 1,569 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Globals initialization using templates


The subject is a bit misleading because I really can't figure out what
the following code snippet is doing and would appreciate any help in
deciphering it.

I mean I can understand code-wise what is going on but I am missing the
larger picture.

In what circumstances would I use this?

template<typename T>
class Globals
{
public:
Globals()
{
if (impl == NULL)
{
init();
}
}
T* operator->() const
{
return impl;
}
private:
static T* impl;
static void init()
{
static union
{
char buf[ sizeof( T ) ] ;
double dummyForAlignment ;
} data ;
impl = new (data.buf) T;
}
};

template<typename T>
T* Globals<T>::impl = NULL;

Nov 16 '06 #1
15 1376

Dilip wrote:
The subject is a bit misleading because I really can't figure out what
the following code snippet is doing and would appreciate any help in
deciphering it.

I mean I can understand code-wise what is going on but I am missing the
larger picture.

In what circumstances would I use this?

template<typename T>
class Globals
{
public:
Globals()
{
if (impl == NULL)
{
init();
}
}
T* operator->() const
{
return impl;
}
private:
static T* impl;
static void init()
{
static union
{
char buf[ sizeof( T ) ] ;
double dummyForAlignment ;
} data ;
impl = new (data.buf) T;
}
};

template<typename T>
T* Globals<T>::impl = NULL;
Defining Globals in a multithreaded environment (even though toe code
here doesnt have any multi threading constructs)where you could control
the order of Initialization especially when you oculd be possibly
having a bunch of globals depending upon each other.

Nov 16 '06 #2
ampar...@gmail.com wrote:
Defining Globals in a multithreaded environment (even though toe code
here doesnt have any multi threading constructs)where you could control
the order of Initialization especially when you oculd be possibly
having a bunch of globals depending upon each other.
can you give me a short example?

I thought the order of initialization for global variables are defined
within a translation unit?
Do you mean cases where global vars defined across translation units
somehow end up depending on one another for initialization? If so, how
does that class solve the problem?

Nov 16 '06 #3
Dilip wrote:
The subject is a bit misleading because I really can't figure out what
the following code snippet is doing and would appreciate any help in
deciphering it.

I mean I can understand code-wise what is going on but I am missing the
larger picture.

In what circumstances would I use this?

template<typename T>
class Globals
{
public:
Globals()
{
if (impl == NULL)
{
init();
}
}
T* operator->() const
{
return impl;
}
// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}
private:
static T* impl;
static void init()
{
static union
{
char buf[ sizeof( T ) ] ;
double dummyForAlignment ;
} data ;
impl = new (data.buf) T;
}
};

template<typename T>
T* Globals<T>::impl = NULL;
Nov 16 '06 #4

Dilip wrote:
ampar...@gmail.com wrote:
Defining Globals in a multithreaded environment (even though toe code
here doesnt have any multi threading constructs)where you could control
the order of Initialization especially when you oculd be possibly
having a bunch of globals depending upon each other.

can you give me a short example?

I thought the order of initialization for global variables are defined
within a translation unit?
Do you mean cases where global vars defined across translation units
somehow end up depending on one another for initialization? If so, how
does that class solve the problem?
what is the following code doing ?

static T* impl;
static void init()
{
static union
{
char buf[ sizeof( T ) ] ;
double dummyForAlignment ;
} data ;
impl = new (data.buf) T;
}

How many times do you think the Init function is called per type ?

Nov 16 '06 #5
red floyd wrote:
// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}
That's not clearly the right thing. impl is a static and so it does not
necessarily need destruction from a memory leaking perspective.
Nov 16 '06 #6

Gianni Mariani wrote:
red floyd wrote:
// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}

That's not clearly the right thing. impl is a static and so it does not
necessarily need destruction from a memory leaking perspective.
impl might be static....but it might be holding a pointer to an object
T which might be holding up stuff. Therefore you need to call the T's
destructor.

Nov 16 '06 #7
Dilip wrote:
The subject is a bit misleading because I really can't figure out what
the following code snippet is doing and would appreciate any help in
deciphering it.

I mean I can understand code-wise what is going on but I am missing the
larger picture.

In what circumstances would I use this?

template<typename T>
class Globals
{
public:
Globals()
{
if (impl == NULL)
{
init();
}
}
T* operator->() const
{
return impl;
}
private:
static T* impl;
static void init()
{
static union
{
char buf[ sizeof( T ) ] ;
double dummyForAlignment ;
} data ;
impl = new (data.buf) T;
}
};

template<typename T>
T* Globals<T>::impl = NULL;
I don't see what some of the constructs are used - why not use this:

template<typename T>
class Globals
{
public:
T* operator->() const
{
static T * x = new T;
return x;
}
};

OK - so the memory for x is dynamically allocated in this example while
the OP example is not.

The use synax would be simply:

Globals<Type>()->Member ...
This below is probably equivalent to what was posted. (i.e. No dynamic
memory allocation.)

template<typename T>
class Globals
{
public:

T* operator->() const
{
static union
{
char buf[ sizeof( T ) ] ;
double dummyForAlignment ;
} data ;
static T * x = new (data.buf) T;
return x;
}
};

Nov 16 '06 #8
am******@gmail.com wrote:
Gianni Mariani wrote:
>red floyd wrote:
>>// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}
That's not clearly the right thing. impl is a static and so it does not
necessarily need destruction from a memory leaking perspective.

impl might be static....but it might be holding a pointer to an object
T which might be holding up stuff. Therefore you need to call the T's
destructor.
That would mean that impl will point to unallocated memory if used like
this:
Globals<Type>()->X(); // ok works first time
Globals<Type>()->Y(); // oops - broken this time
Nov 16 '06 #9
Gianni Mariani wrote:
red floyd wrote:
>// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}

That's not clearly the right thing. impl is a static and so it does not
necessarily need destruction from a memory leaking perspective.
Who said anything about memory? T could be a type that manages a
resource that could conceivably live beyond the lifetime of the program,
e.g. a SysV Semaphore.

When the program ends, Global<my_semaphore_manager_classshould bloody
well call the destructor for the my_semaphore_manager_class object it
created in impl, so that it can release the resource it holds.

Nov 16 '06 #10

Gianni Mariani wrote:
am******@gmail.com wrote:
Gianni Mariani wrote:
red floyd wrote:

// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}
That's not clearly the right thing. impl is a static and so it does not
necessarily need destruction from a memory leaking perspective.
impl might be static....but it might be holding a pointer to an object
T which might be holding up stuff. Therefore you need to call the T's
destructor.

That would mean that impl will point to unallocated memory if used like
this:
Globals<Type>()->X(); // ok works first time
Globals<Type>()->Y(); // oops - broken this time
I dont understand this code above....
But you need some kind of descurtion on a refcount basis....

Nov 16 '06 #11
red floyd wrote:
Gianni Mariani wrote:
>red floyd wrote:
>>// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}

That's not clearly the right thing. impl is a static and so it does
not necessarily need destruction from a memory leaking perspective.

Who said anything about memory? T could be a type that manages a
resource that could conceivably live beyond the lifetime of the program,
e.g. a SysV Semaphore.

When the program ends, Global<my_semaphore_manager_classshould bloody
well call the destructor for the my_semaphore_manager_class object it
created in impl, so that it can release the resource it holds.
We have no idea what this is used for. Clearly there is no destructor
and possibly for good reason. Saying it "should bloody well" have one
is making many assumptions that may not be valid.

Nov 17 '06 #12
Gianni Mariani wrote:
red floyd wrote:
>Gianni Mariani wrote:
>>red floyd wrote:

// missing destructor
// this is necessary in case T manages some kind of resource.
~Globals()
{
impl->T::~T();
}

That's not clearly the right thing. impl is a static and so it does
not necessarily need destruction from a memory leaking perspective.

Who said anything about memory? T could be a type that manages a
resource that could conceivably live beyond the lifetime of the
program, e.g. a SysV Semaphore.

When the program ends, Global<my_semaphore_manager_classshould
bloody well call the destructor for the my_semaphore_manager_class
object it created in impl, so that it can release the resource it holds.

We have no idea what this is used for. Clearly there is no destructor
and possibly for good reason. Saying it "should bloody well" have one
is making many assumptions that may not be valid.
Exactly. We have no idea what this is used for. Therefore is should
behave properly in the case where the template parameter has a
non-trivial destructor.
Nov 17 '06 #13
red floyd wrote:
....
Exactly. We have no idea what this is used for. Therefore is should
behave properly in the case where the template parameter has a
non-trivial destructor.
Can you make a logical argument why is "requires" a destructor making no
assumptions ?
Nov 17 '06 #14
Gianni Mariani wrote:
red floyd wrote:
...
>Exactly. We have no idea what this is used for. Therefore is should
behave properly in the case where the template parameter has a
non-trivial destructor.

Can you make a logical argument why is "requires" a destructor making no
assumptions ?
Because if T has a trivial destructor, then no harm is done by invoking
its destructor. If T has a non-trivial destructor, then failure to
invoke it can cause problems. Therefore, the destructor should be invoked.
Nov 17 '06 #15
red floyd wrote:
....
>
Because if T has a trivial destructor, then no harm is done by invoking
its destructor.
I don't think "no harm" is entirely clear. I'm not suggesting this is
good code, but there have been badly designed systems where I have
needed to not call the destructor on system exit because bad things
would in fact happen. Hence, as a generalization, I don't think "no
harm" is supportable.
... If T has a non-trivial destructor, then failure to
invoke it can cause problems. Therefore, the destructor should be invoked.
Not all non-trivial destructors (for globals) need to be called. The
operating system does a much more efficient cleanup on exit than a

e.g. this code (brain dump - not checked)

#include <vector>
std::vector<int> * foo = new std::vector<int>(10000000);

int main()
{
}

will not delete the object pointed to by foo, however on all popular
operating systems (I don't talk about embedded ones), this code is well
behaved.

In general, you can't really bargain on global destructors being called
anyway because there are ways of termination that do not call the final
cleanup routines (memory fault, power failure, failure to catch
exception, memory depletion, unresovable page faults etc just to mention
some). So if your code truly depends on global destructors to be
called, you're in for trouble.

For example, if your code uses temporary files, you may want to "lock"
the file and on startup, cleanup all unlocked temporary files. You
could do the same for all persistent OS objects.

So the point is, your generalization is clearly incorrect. While it is
"preferable" to have destructors of global objects called, it is
certainly not required all the time and it certainly cannot be depended
on all the time.

All generalizations are wrong.

Nov 17 '06 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Nel | last post by:
I have a question related to the "security" issues posed by Globals ON. It is good programming technique IMO to initialise variables, even if it's just $foo = 0; $bar = ""; Surely it would...
5
by: Frostillicus | last post by:
I'm trying to use array_multisort to sort by one of the dimensions of an array stored in $GLOBALS like this: array_multisort($GLOBALS, SORT_STRING, SORT_DESC); Each "row" in $GLOBALS contains...
8
by: Ron_Adam | last post by:
Is there a way to hide global names from a function or class? I want to be sure that a function doesn't use any global variables by mistake. So hiding them would force a name error in the case...
3
by: Brian Ross | last post by:
Hi, I am having a problem writing a constructor/member initialization with VC.NET7.1. Here is the code: --- namespace Library
5
by: jgraveskc | last post by:
I know this sounds nasty, but let me explain. I have what was a class that contains a whole buncha function pointers (for OpenGL extensions) that are used in the app. I was porting this app to...
6
by: srblinux | last post by:
Hi all, If a program-1 is written with Globals without initilisation and program-2 was written with Globals with initilisation, But program-2 is working fine but program-1 is giving problem why...
15
by: akomiakov | last post by:
Is there a technical reason why one can't initialize a cost static non- integral data member in a class?
3
by: Gianni Mariani | last post by:
So I was put straight that double(v) is the same as (double)(v) recently and I'm somewhat surprised. I'm not the only one. I think T(V) should have exactly the same semantics as...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.