Reputation: 22821
Please, tell me from where execution starts in c++, hope your answer is "from main".
Then what about this?
class abc
{
public:
abc()
{
cout<<"hello";
}
};
const abc obj;
int main( )
{
cout<<"Main";
}
output:
helloMain
Please elaborate.
Upvotes: 3
Views: 546
Reputation: 98425
What happens is implied by the meaning of the code you wrote. That meaning is defined by the C++ standard.
The standard guarantees that by the time main()
starts running, all global objects are available for use, i.e. they have been constructed. Thus, if an object's construction has side effects observable from "outside" the program - like I/O - those side effect must happen before main()
gets called.
C++ guarantees more, though. All objects that are in scope must be available, i.e. constructed. No matter what the scope is. Since global variables are in scope of main()
, they must be constructed before main()
is called. But this applies to all other scopes.
You can try running the code below interactively in a debugger online and see exactly what happens.
#include <iostream>
struct Hello {
static int counter;
int this_counter = counter++;
Hello() { std::cout << "Hello " << this_counter << std::endl; }
~Hello() { std::cout << "Goodbye " << this_counter << std::endl; }
static void say_hello() {
int this_counter = counter++;
std::cout << "Hello and goodbye " << this_counter << std::endl;
}
};
int Hello::counter = 1;
const Hello hello1;
void hello4() { // scope 4
Hello hello4;
// scope 4+ - hello4 is in that scope
}
int main()
{ // entering scope 2
Hello hello2;
// scope 2+ - hello2 is in that scope
Hello::say_hello(); // hello3
hello4();
}
Upvotes: 0
Reputation: 7864
From your comments to the other answers strut, it sounds like a 10,000 foot view might assist in understanding.
The exact steps involved in launching an application differs between OSes, compilers, and programming languages but the "general" process is essentially the same.
int __entry( int argc, char *argv[] )
{
// configure standard I/O streams, threading tables, & other utilities
initialize_c_runtime();
// run the constructors for all static objects
initialize_static_cplusplus_objects();
// Now, finally, after *all* that we execute the 'main' function
return main(argc, argv);
}
Upvotes: 7
Reputation: 59451
Global variables are created (and hence their constructors called) before main
is invoked.
Answer to OP's comment:
If you want to dig deeper than the code written by you, there are things happening before main
is invoked, of which I myself don't have a clear picture. I am talking about the code that we write - where the entry point is the main
function, which is invoked after initializing the global variables. As it happens, initialization of a class instance means calling its constructor.
Hence in short, the line const abc obj;
creates a global variable of type abc
which is initialized (it's default constructor with a print statement is called) before the main
is called. Hence the output helloMain
Upvotes: 13
Reputation: 16129
An application does not start from main. Following are some stack snapshots from the start of main (for a console app, unicode version) compiled with VS2005:
myapp.exe!wmain(int argc=0x00000001, wchar_t * * argv=0x00364d68) Line 67 C++
myapp.exe!__tmainCRTStartup() Line 594 + 0x17 bytes kernel32.dll!_BaseProcessStart@4() + 0x23 bytes
The first function that can be said to run in the new process context in user mode is BaseProcessStart, which is a Win32 level function. It calls the CRT-level mainCRTStartup, which uses various data sections in the binary image itself to run various initializers - e.g., global constructors such as your obj. In fact, you can set a breakpoint in your ctor and watch it yourself:
myapp.exe!`dynamic initializer for'obj''()
msvcr80.dll!_initterm(...)
myapp.exe!__tmainCRTStartup()
kernel32.dll!_BaseProcessStart@4()
(Having some formatting difficulties there). initterm is the function that iterates on global objects and calls their constructors.
The stacks would look different on different platforms and compilers (and even on VS, very different for an MFC app) but the idea is always the same: the runtime uses binary image info to initialize global objects before your own main is entered.
Upvotes: 0
Reputation: 29166
Since obj
is a global object, it will be instantiated before main
executes. It is just like any other global variables, i.e., when you declare an integer variable as global, it contains 0, not any garbage value. So, your object is instantiating, and calling the constructor which in turn prints the hello
string.
Upvotes: 0
Reputation: 35731
You declared obj
as a const variable of class abc
. The variable obj
is assigned a default value before your program starts execution by code that is emmited by the compiler. This code calls the default constructor to create a default object of type abc
and assigns it to obj
.
Leaving static initializations aside, it's correct to say execution starts from main()
.
Upvotes: 3