Dead reference Problem and its detection

In Meyer's singleton pattern, we saw how we can use meyer's implementation approach of singleton design pattern to destroy the singleton object efficiently. It seems perfect at the first glance. However, it has certain problem called Dead reference problem. Let us try to understand it with the help of an example :

Let us say there are two static objects of class A and B and we have a singleton design pattern class called log that errors out if there is some error in creation or deletion of A or B. As we had studied in the last post that singleton object is created in Instance() function when it is called first time. A and B calls Instance() function of log while initialization and destruction if there occurs some error. Let us say object of A got created successfully  but while constructing object of B there comes some error and it calls Instance() function of log Hence singleton object got created and possibly whole application exits out after this. Since compiler destroys local static object in the reverse order of their creation Hence log will be destroyed before object of A and let us say there occurs some error in destruction of A Instance() function return an Invalid object and program can behave unexpected. This is called dead reference problem.

Before thinking its solution we should understand what the real problem is. Problem is that we do not know the order of creation of object of A,B and log. A and B should follow the C++ rule(last object created first) but log should be exempted from this rule. log should destroyed after destruction of A and B so that it can catch all errors thrown by creation or destroy of A and B.

We have no way yet to control lifetime of objects (at least not in this post) but we can atleast detect dead reference problem that can be done by keeping a static bool variable called deleted_ inside singleton class which is initialized to false  and set to true in its destructor.


class Singelton {
   static bool deleted_;
public :
  Singleton& Instance() {
    if( !deleted ) {
          static singleton obj;
         return obj;
    } else {
        throw std::runtime_error("dead reference detected") ;
    }
 }

 ~Singeton() {
     inst_ = 0;
    deleted_ = true;
  }
};

bool Singleton::deleted_ = false;

If some object tries to access singleton after its destruction, It will throw an error.

How to automatically include header dependencies in makefile

Why automate inclusion of header file dependencies: While working on a new project, I had to write a makefile from scratch. I found it little challenging to find out how to automatically include header dependencies in makefile, because everytime you include some header file in your source file, you can not modify your makefile. So, I thought, there must be some mechanism that automatically takes care of it. If you search on google, you will find various ways. Manual solution is to use sed command that I guess searches for #includes in your source code and puts all those dependencies in your makefile. But with modern compiler, you dont need to do much. It will do your job. You just need to pass some flags to it.


For instance, with gcc version 4.1.2 20080704 (Red Hat 4.1.2-51), before including header dependencies, target to make object file was


./%.o : ../%.cpp
     g++ -c $(INC_PATH) $(FLAGS)  $< -o $@
./%.o : ../%.cpp
     g++ -c $(INC_PATH) $(FLAGS) -MMD -MP $< -o $@

-include $(SRC_FILES:.cpp=.d)

you just need to pass -MMD and _MP flag and need to include these dependencies (.d file).


 See the below example that demonstrate it

Let us say we have 3 c++ and 3 header files :


  1. test.cxx
  2. add.cxx
  3. sub.cxx
  4. test.h
  5. sub.h
  6. add.h
add.cxx includes add.h
sub.cxx includes sub.h
test.cxx includes test.h , add.h and sub.h

Following is the makefile that only includes dependencies of .cxx files  :

---------------------------------------------------------------------------------
### declaration of all variables
FLAGS := -g
COMPILER := g++
SRC_FILES := $(wildcard *.cxx)
OBJ_FILES := $(SRC_FILES:%.cxx=%.o)
.PHONY  : all clean
EXE := my_exe
STATIC_LIB := my_exe.a
all : $(EXE)

### compile source files to make object files
### expand this section for each object file to include dependency of header files
## NAAAA I am not gonna do it..  :P
%.o : %.cxx
        $(COMPILER) -c $(FLAGS) $< -o $@

### make static libary of object files
$(STATIC_LIB) : $(OBJ_FILES)
    ar -crv $@ $^

### make executable  
$(EXE) : $(STATIC_LIB)
    $(COMPILER) $^ -o $@

# clean all the files
clean :
    rm -rf $(OBJ_FILES) $(EXE) $(STATIC_LIB)
---------------------------------------------------------------------------------


If you do any changes in .h file and try to do "make" it will say nothing to be done for 'all'  as we have no where mentioned that any of my target depends on header file.

Hence,  to include dependency of header files I should explicitly include header files in my makefile but what if I add one more header file in test.cxx? I will again need to modify makefile which is a cumbersome task and non-practical in a real project.

Today compiler provides you facility to automatically generate dependency graph. All you need to do is to just pass some flags.

e.g. with g++ compiler you should give -MMD -MP flag. It will generate dependency file(.d) for each object file and include those dependency files in makefile as follow :

---------------------------------------------------------------------------------
## not including variable declaration part

%.o : %.cxx
        $(COMPILER) -c $(FLAGS) -MMD -MP $< -o $@

### include all dependency files

-include $(SRC_FILES:.cxx=.d)

$(STATIC_LIB) : $(OBJ_FILES)
    ar -crv $@ $^
   
$(EXE) : $(STATIC_LIB)
    $(COMPILER) $^ -o $@

clean :
    rm -rf $(OBJ_FILES) $(EXE) $(STATIC_LIB)
---------------------------------------------------------------------------------

Test.d : 


test.o: test.cxx add.h sub.h test.h

add.h:

sub.h:

test.h:

This is how a dependency files look like. Now test.o depends on  test.h, add.h and sub.h along with test.cxx. similarly add.o includes dependency of add.h and sub.o takes sub.h into account.

Whenever time stamp of any of header file changes corresponding object file will be modified that solves our purpose. :)