Using the keyword 'new' in file scope? - c++

Given this class in the header file:
class ClassA
{
public:
ClassA(){};
}
Then in file.cpp
#include file.h
ClassA* GlobalPointerToClassAType = new ClassA();
a. Is it allowed, and is it good practice to use the keyword 'new' to allocate memory for an object in the heap(?) in lines of file-scope?
b. If it is allowed, then when exactly does the constructor ClassA() is actually called?
c. How does it differ if I wrote instead this line:
ClassA GlobalInstanceOfClassAType = ClassA();
in terms of the time of calling the constructor, in terms of memory efficiency, and in terms of good practice?

a. Is it allowed, and is it good practice to use the keyword 'new' to allocate memory for an object in the heap(?) in lines of file-scope?
It is allowed. Whether is it good practice to use new here is opinion based. And i predict that most people will answer no.
b. If it is allowed, then when exactly does the constructor ClassA() is actually called?
Let's start from some concepts.
In C++, all objects in a program have one of the following storage durations:
automatic
static
thread (since C++11)
dynamic
And if you check the cppreference, it claim:
static storage duration. The storage for the object is allocated when the program begins and deallocated when the program ends. Only one instance of the object exists. All objects declared at namespace scope (including global namespace) have this storage duration, plus those declared with static or extern. See Non-local variables and Static local variables for details on initialization of objects with this storage duration.
So, GlobalPointerToClassAType has static storage duration, it fit the statement that "All objects declared at namespace scope (including global namespace) have this storage duration...".
And if you get deeper into the link of the above section, you will find:
All non-local variables with static storage duration are initialized as part of program startup, before the execution of the main function begins (unless deferred, see below). All non-local variables with thread-local storage duration are initialized as part of thread launch, sequenced-before the execution of the thread function begins. For both of these classes of variables, initialization occurs in two distinct stages:
There's more detail in the same site, you can go deeper if you want to get more, but for this question, let's only focus on the initialization time. According to the reference, The constructor ClassA() might be called before the execution of the main function begins (unless deferred).
What is "deferred"? The answer is in the below sections:
It is implementation-defined whether dynamic initialization happens-before the first statement of the main function (for statics) or the initial function of the thread (for thread-locals), or deferred to happen after.
If the initialization of a non-inline variable (since C++17) is deferred to happen after the first statement of main/thread function, it happens before the first odr-use of any variable with static/thread storage duration defined in the same translation unit as the variable to be initialized. If no variable or function is odr-used from a given translation unit, the non-local variables defined in that translation unit may never be initialized (this models the behavior of an on-demand dynamic library). However, as long as anything from a translation unit is odr-used, all non-local variables whose initialization or destruction has side effects will be initialized even if they are not used in the program.
Let's see a tiny example, from godbolt. I use clang, directly copy your code, except that the Class A and main are defined in the same translation unit. You can see clang generate some section like __cxx_global_var_init, where the class ctor is called.

Related

Why static instance constructor not called at second time? [duplicate]

The book Object oriented programming in c++ by Robert Lafore says,
A static local variable has the visibility of an automatic local
variable (that is, inside the function containing it). However, its
lifetime is the same as that of a global variable, except that it
doesn’t come into existence until the first call to the function
containing it. Thereafter it remains in existence for the life of the
program
What does coming into existence after first call of function mean? The storage for static local is allocated at the time program is loaded in the memory.
The storage is allocated before main is entered, but (for example) if the static object has a ctor with side effects, those side effects might be delayed until just before the first time the function is called.
Note, however, that this is not necessarily the case. Constant initialization is only required to happen before that block is entered (not necessarily just as execution "crosses" that definition). Likewise, implementations are allowed to initialize other block-scope static variables earlier than required under some circumstances (if you want to get into the gory details of the circumstances, you can look at [basic.start.init] and [stmt.dcl], but it basically comes down to: as long as it doesn't affect the value with which it's initialized. For example, if you had something like:
int i;
std::cin >> i;
{
static int x = i;
...the implementation wouldn't be able to initialize x until the block was entered, because the value with which it was being initialized wouldn't be known until them. On the other hand, if you had:
{
static int i = 0;
...the implementation could carry out the initialization as early as it wished (and most would/will basically carry out such an initialization at compile time, so it won't involve executing any instructions at run-time at all). Even for less trivial cases, however, earlier initialization is allowed when logically possible (e.g., the value isn't coming from previous execution).
In C++ storage duration of an object (when raw memory gets allocated for it) and lifetime of an object are two separate concepts. The author was apparently referring to the latter one when he was talking about object's "coming into existence".
In general case it is not enough to allocate storage for an object to make it "come into existence". Lifetime of an object with non-trivial initialization begins once its initialization is complete. For example, an object of a class with a non-trivial constructor does not officially "live" until its constructor has completed execution.
Initialization of a static local object is performed when the control passes over the declaration for the very first time. Before that the object does not officially exist, even if the memory for it is already allocated.
Note that the author is not painstakingly precise in his description. It is not sufficient to just call the function containing the declaration. The control has to pass through the declaration of the object for it to begin its lifetime. If the function contains branching, this does not necessarily happen during the very first call to the function.
For object with trivial initialization (like int objects), there's no difference between storage duration and lifetime. For such objects allocating memory is all that needs to be done. But in general case allocating memory alone is not sufficient.
It means that the static variable inside a function doesn't get initialized (by the constructor or the assignment operator) until the first call for that function.
As soon as the function, which contains a static local variable, is called the static local variable is initialized.

When is a `static const std::map` initialized, when not a member of class? [duplicate]

I'm working on some C++ code and I've run into a question which has been nagging me for a while... Assuming I'm compiling with GCC on a Linux host for an ELF target, where are global static constructors and destructors called?
I've heard there's a function _init in crtbegin.o, and a function _fini in crtend.o. Are these called by crt0.o? Or does the dynamic linker actually detect their presence in the loaded binary and call them? If so, when does it actually call them?
I'm mainly interested to know so I can understand what's happening behind the scenes as my code is loaded, executed, and then unloaded at runtime.
Thanks in advance!
Update: I'm basically trying to figure out the general time at which the constructors are called. I don't want to make assumptions in my code based on this information, it's more or less to get a better understanding of what's happening at the lower levels when my program loads. I understand this is quite OS-specific, but I have tried to narrow it down a little in this question.
When talking about non-local static objects there are not many guarantees. As you already know (and it's also been mentioned here), it should not write code that depends on that. The static initialization order fiasco...
Static objects goes through a two-phase initialization: static initialization and dynamic initialization. The former happens first and performs zero-initialization or initialization by constant expressions. The latter happens after all static initialization is done. This is when constructors are called, for example.
In general, this initialization happens at some time before main(). However, as opposed to what many people think even that is not guaranteed by the C++ standard. What is in fact guaranteed is that the initialization is done before the use of any function or object defined in the same translation unit as the object being initialized. Notice that this is not OS specific. This is C++ rules. Here's a quote from the Standard:
It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of
namespace scope is done before the first statement of main. If the initialization is deferred to some point
in time after the first statement of main, it shall occur before the first use of any function or object defined
in the same translation unit as the object to be initialized
This depends heavy on the compiler and runtime. It's not a good idea to make any assumptions on the time global objects are constructed.
This is especially a problem if you have a static object which depends on another one being already constructed.
This is called "static initialization order fiasco". Even if thats not the case in your code, the C++Lite FAQ articles on that topic are worth a read.
This is not OS specific, rather its compiler specific.
You have given the answer, initialization is done in __init.
For the second part, in gcc you can guarantee the order of initialization with a __attribute__((init_priority(PRIORITY))) attached to a variable definition, where PRIORITY is some relative value, with lower numbers initialized first.
The grantees you have:
All static non-local objects in the global namespace are constructed before main()
All static non-local objects in another namespace are constructed before any functions/methods in that namespace are used (Thus allowing the compiler to potentially lazy evaluate them [but don't count on this behavior]).
All static non-local objects in a translation unit are constructed in the order of declaration.
Nothing is defined about the order between translation units.
All static non-local objects are destroyed in the reverse order of creation. (This includes the static function variables (which are lazily created on first use).
If you have globals that have dependencies on each other you have two options:
Put them in the same translation unit.
Transform them into static function variables retrieved and constructed on first use.
Example 1: Global A's constructor uses Global log
class AType
{ AType() { log.report("A Constructed");}};
LogType log;
AType A;
// Or
Class AType()
{ AType() { getLog().report("A Constructed");}};
LogType& getLog()
{
static LogType log;
return log;
}
// Define A anywhere;
Example Global B's destructor uses Global log
Here you have to grantee that the object log is not destroyed before the object B. This means that log must be fully constructed before B (as the reverse order of destruction rule will then apply). Again the same techniques can be used. Either put them in the same translation unit or use a function to get log.
class BType
{ ~BType() { log.report("B Destroyed");}};
LogType log;
BType B; // B constructed after log (so B will be destroyed first)
// Or
Class BType()
{ BType() { getLog();}
/*
* If log is used in the destructor then it must not be destroyed before B
* This means it must be constructed before B
* (reverse order destruction guarantees that it will then be destroyed after B)
*
* To achieve this just call the getLog() function in the constructor.
* This means that 'log' will be fully constructed before this object.
* This means it will be destroyed after and thus safe to use in the destructor.
*/
~BType() { getLog().report("B Destroyed");}
};
LogType& getLog()
{
static LogType log;
return log;
}
// Define B anywhere;
According to the C++ standard they are called before any function or object of their translation unit is used. Note that for objects in the global namespace this would mean they are initialized before main() is called. (See ltcmelo's and Martin's answers for mote details and a discussion of this.)

Lifetime of primitive globals relative to class statics

Question coming from another question I recently asked Referencing a possibly destroyed static object. Can a destructor for an instance of a class use a global primitive variable/constant? Is it guaranteed to hold its value till program termination (i.e. after the statics have been destroyed)?
I know that static object destruction across compilation units is not defined but I was wondering whether the same holds for primitive values.
For example
Something.cpp
extern bool global_boolean_value;
Something::~Something() {
assert(global_boolean_value);
}
With respect to initialization the standard lumps together everything with "static storage duration", which are the variables (including member variables) declared using the static keyword (variables with internal linkage) as well as "true globals" (variables with external linkage). The standard does not distinguish between plain old data types one one hand and structs or classes on the other.
Note after comments (all quotes from the 2012 standard):
3.7.1 Static storage duration [basic.stc.static]
1 All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program (3.6.2, 3.6.3).
(Emphasis by me.) There is no distinction between PODs and non-PODs. Note that the paragraph defines the lifetime of the storage, not of the (typed, initialized) object. When the program (not main()!) starts, all static storage is readily allocated. And yes, the destructors of objects with static storage duration are part of the program. This makes it, as far as I can see, safe to access errno in a destructor.
As you say, there is no guarantee about the order of initialization of objects with static storage duration across different translation units; within one TU the initialization is performed in the definition order, and destruction is then done in the opposite order.
That is all there is to it (apart from workarounds, like putting your globals in an artificial class or returning static local variables from functions).
The answer to your example question then depends on the storage duration of the object for which the destructor is called. If the object has static storage duration and is in a different translation unit, you are out of luck. If it is automatically or dynamically allocated, or if it is defined in the same translation unit after the global variable you are fine.

C++ static member variable scope

The title basically says it all, i wonder when static members of a c++ class are initialized and when they go out of scope.
I need this for the following problem. I have many objects of a class Foo and each object needs access to a resource, encapsulated by another class Bar. Synchronization is not an issue, so i want all objects to share the same Bar instance.
I'm using a simple managed pointer for reference counting.
Can i do the following:
class Foo {
private:
static managed_pointer<Bar> staticBar;
public:
Foo() {
if(!staticBar)
staticBar = new Bar;
}
/*
* use staticBar in various non-static member functions
*/
};
managed_pointer<Bar> Foo::staticBar = NULL;
the managed_pointer staticBar should delete the Bar object as soon as it goes out of scope - but when does this happen? when the last instance of Foo is destructed? on application exit?
Thanks for your advice!
statics and globals are initialized right before the program starts (before main is called, the program actually starts before that) and go out of scope after main exits.
Exceptions - local statics (static variables declared inside functions) and unused template class staticmembers.
It has nothing to do with the number of instances.
The standard does not specify a precise order of initialization, it is implementation specific. They will be instantiated at the start of the program and deallocated at the end.
You have to be very careful with what you are doing, because if you have some other static objects that rely on this object to exist, it's UB. There is no telling in what order they will be initialized.
You could possibly look into something like boost::call_once to ensure it's initialized once, but I wouldn't rely on the order the statics are initialized.
For all I know, you code would work, but I've been bitten by the static initialization issue before so I wanted to warn you.
EDIT: Also in your code, when the managed_ptr will go out of scope (end of program), it will delete the memory allocated automatically. But you should not do anything non-trivial in Bar's destructor as you may trigger UB by calling into other free'd instances or even code that has been removed (as it happened to me once where a dynamic library had been removed). Essentially you are in a minefield, so watch out.
The first thing that pops out of your question is the common misconception that scope and lifetime are equivalent concepts. They are not. In some cases as with local variables, the lifetime is bound to a particular context, but that is not always the case.
A class static member variable has class scope (it is accessible anywhere in the program) and static lifetime, which means that it will be initialized in order with respect to the other static variables in the same translation unit, and in an undefined order with respect to other static variables in other translation units, before main (caveat: initialization need not be performed before the first statement in main, but it is guaranteed to be before the first odr-use of the variable).

C++: When (and how) are C++ Global Static Constructors Called?

I'm working on some C++ code and I've run into a question which has been nagging me for a while... Assuming I'm compiling with GCC on a Linux host for an ELF target, where are global static constructors and destructors called?
I've heard there's a function _init in crtbegin.o, and a function _fini in crtend.o. Are these called by crt0.o? Or does the dynamic linker actually detect their presence in the loaded binary and call them? If so, when does it actually call them?
I'm mainly interested to know so I can understand what's happening behind the scenes as my code is loaded, executed, and then unloaded at runtime.
Thanks in advance!
Update: I'm basically trying to figure out the general time at which the constructors are called. I don't want to make assumptions in my code based on this information, it's more or less to get a better understanding of what's happening at the lower levels when my program loads. I understand this is quite OS-specific, but I have tried to narrow it down a little in this question.
When talking about non-local static objects there are not many guarantees. As you already know (and it's also been mentioned here), it should not write code that depends on that. The static initialization order fiasco...
Static objects goes through a two-phase initialization: static initialization and dynamic initialization. The former happens first and performs zero-initialization or initialization by constant expressions. The latter happens after all static initialization is done. This is when constructors are called, for example.
In general, this initialization happens at some time before main(). However, as opposed to what many people think even that is not guaranteed by the C++ standard. What is in fact guaranteed is that the initialization is done before the use of any function or object defined in the same translation unit as the object being initialized. Notice that this is not OS specific. This is C++ rules. Here's a quote from the Standard:
It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of
namespace scope is done before the first statement of main. If the initialization is deferred to some point
in time after the first statement of main, it shall occur before the first use of any function or object defined
in the same translation unit as the object to be initialized
This depends heavy on the compiler and runtime. It's not a good idea to make any assumptions on the time global objects are constructed.
This is especially a problem if you have a static object which depends on another one being already constructed.
This is called "static initialization order fiasco". Even if thats not the case in your code, the C++Lite FAQ articles on that topic are worth a read.
This is not OS specific, rather its compiler specific.
You have given the answer, initialization is done in __init.
For the second part, in gcc you can guarantee the order of initialization with a __attribute__((init_priority(PRIORITY))) attached to a variable definition, where PRIORITY is some relative value, with lower numbers initialized first.
The grantees you have:
All static non-local objects in the global namespace are constructed before main()
All static non-local objects in another namespace are constructed before any functions/methods in that namespace are used (Thus allowing the compiler to potentially lazy evaluate them [but don't count on this behavior]).
All static non-local objects in a translation unit are constructed in the order of declaration.
Nothing is defined about the order between translation units.
All static non-local objects are destroyed in the reverse order of creation. (This includes the static function variables (which are lazily created on first use).
If you have globals that have dependencies on each other you have two options:
Put them in the same translation unit.
Transform them into static function variables retrieved and constructed on first use.
Example 1: Global A's constructor uses Global log
class AType
{ AType() { log.report("A Constructed");}};
LogType log;
AType A;
// Or
Class AType()
{ AType() { getLog().report("A Constructed");}};
LogType& getLog()
{
static LogType log;
return log;
}
// Define A anywhere;
Example Global B's destructor uses Global log
Here you have to grantee that the object log is not destroyed before the object B. This means that log must be fully constructed before B (as the reverse order of destruction rule will then apply). Again the same techniques can be used. Either put them in the same translation unit or use a function to get log.
class BType
{ ~BType() { log.report("B Destroyed");}};
LogType log;
BType B; // B constructed after log (so B will be destroyed first)
// Or
Class BType()
{ BType() { getLog();}
/*
* If log is used in the destructor then it must not be destroyed before B
* This means it must be constructed before B
* (reverse order destruction guarantees that it will then be destroyed after B)
*
* To achieve this just call the getLog() function in the constructor.
* This means that 'log' will be fully constructed before this object.
* This means it will be destroyed after and thus safe to use in the destructor.
*/
~BType() { getLog().report("B Destroyed");}
};
LogType& getLog()
{
static LogType log;
return log;
}
// Define B anywhere;
According to the C++ standard they are called before any function or object of their translation unit is used. Note that for objects in the global namespace this would mean they are initialized before main() is called. (See ltcmelo's and Martin's answers for mote details and a discussion of this.)