Search code examples
c++gcclinkerstatic-linkingstatic-initialization

static member explicit definition


Consider this code:

#include<iostream>
using namespace std;
class Wilma
{
    public:
        static int i;
        Wilma()
        {
            cout<<"\nWilma ctor\n";
            cout<<"\ni::"<<i<<"\n";
        }
};
class Fred
{
    public:
        Fred()
        {
            cout<<"\nFred ctor\n";

        }
        static Wilma wilma_;
};
int Wilma::i=44;//------------- LINE A
int main()
{
    int a=0;
    Wilma::i=a;//---------- LINE C
    Wilma w;
    Fred::wilma_=w;//---------- LINE B

}

here line A explicitly defines the static int a of Wilma class.(commented out to cause linker error) and without which the linker gives undefined reference error.(because Wilma::i is actually being used,if i dont use it no linker errors are there.)

Same should be true for static Wilma wilma_ of Fred class,i.e it should be explicitly defined aswell..because it is also being used in the code at line B. But thats not the case,no linker errors for Fred::wilma_ if its not been explicitly defined. why? Tested on gcc 4.5.2

EDIT: I somehow got another doubt about this...

LINE C and LINE B both are trying to use static objects of a class,int Wilma::i and Wilma Fred::wilma_ respectively. But only a definition for int Wilma::i is mandatory?

Why isnt Wilma Fred::wilma_; mandatory?

I understand the answer that the line B is a no-op. but same can be said about line C too??


Solution

  • Wilma has no non-static fields. Fred::wilma_=w; doesn't do anything.

    edit

    If there are no non-static members - there's no copy. Basically the assignment was a no-op and might just been optimized out by the compiler, and the linker never saw it. Adding a non-static member made the copy to be an actual operation that referenced the static variable, thus the compiler couldn't optimize it out and the linker saw it.