user3855021
user3855021

Reputation: 21

How is the unused static object initialized?

The code is:

A.h

#ifndef A_H
#define A_H
class A
{
    public:
        A();
};

#endif // A_H

A.cpp

#include "A.h"
#include <iostream>
A::A()
{
    std::cout<<"A()"<<std::endl;
}
static A a;

B.h

#ifndef B_H
#define B_H
class A;
class B
{
    public:
        B();
        static A a;
};
#endif // B_H

B.cpp

#include "B.h"
#include "A.h"
A B::a;
B::B()
{
    //ctor
}

main.cpp

#include <iostream>
using namespace std;
int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

Here is the first case, and the output:

g++ main.cpp A.cpp B.cpp -o test

console output is:

A()
A()
Hello world!

And the second case, and the output:

g++ main.cpp -o test

console output is:

Hello world!

I am confused with this result, how the static object in local file and the static member in class initialized if we just needn't use them in our main program.

Upvotes: 2

Views: 623

Answers (2)

Dov
Dov

Reputation: 8542

The static keyword in C++ is used in multiple contexts. Some come from C, and some are new.

Here are the old meanings:

int x; // this is global, it is initialized when the program is loaded
static int y; // just like global but only visible local to the file.

The old meaning of static was like a global, but visible only within the file. Like global variables, static variables are born before main begins, and die after it ends. This is why in your example, the constructors are called before main. Unfortunately, the order of global constructors is not defined, which can be a pain. If you need some objects to be created before others, you have a problem.

When classes were added, in an attempt not to take other keywords, the language reused existing symbols in new ways that were related, but different. For example, references use the & symbol in a new way, because they involve pointers. Anyway, in a class, static means shared by the entire class.

class A {
private:
  static int x;

};

The variable x inside class A is not created for each instance of A. Even before you create the first object of type A, x exists. It cannot be global, because if it were, when you include the class in two separate files, you would be creating two identical global variables (multiple symbol definition)

Instead, static turns into extern. This means that you are declaring that inside A, there is a symbol called x that is an integer. Someone has to define that symbol. Typically, in A.cc:

#include "A.h"
int A::x = 0;

You don't have to define x is zero, it would default to that anyway because it is a global, but it's always better to define it explicitly so it's obvious to everyone.

Once you have a static variable, then you need a function to access it. A static function is inside the class, but is not a method. So:

class A {
private:
  private static int count;
public:
  A() {
    count++; // increment count every time an object of type A is created
  }
  ~A() {
    count--;
  }
  static int getCount() { return count; }
};

To find out how many objects of type A exist:

cout << A::getCount();

If this method were not static, the only way to ask would be:

A a1;
cout << a1.getCount();

So you could never get an answer of 0, since in order to ask you would have to create an object of type A.

Your example differs only in the fact that you have created objects of type A rather than a builtin type.

Upvotes: 0

user123
user123

Reputation: 9071

Both of these object instances are initialized before main is called.
Their destructors will be called after main's execution ends as well.

Whether you use them or not doesn't actually matter. Also, you're compiling with no optimizations. That's why the unreferenced objects are not being addressed.

Upvotes: 1

Related Questions