You want:

    addrspace.h to include synch.h
    synch.h includes thread.h
    thread.h include addrspace.h

But this forms a cycle - the compiler can't determine how much space to a class is going to need.

In order to do this:

    in addrspace.h  - do not include synch.h but only put a statement
    referring to the classes that you are going to use.  E.g.
        class Lock;
        class Semaphore;
    in addrspace.cc you'll have to include synch.h (which will be fine).

Using this method you can only use pointers to the classes whose definitions you have not included (because the compiler needs to know how much space to preserve for them and it knows that a pointer to any class uses the same amount of space). It doesn't know what the class looks like yet so it can not figure out how much space to preserve for the actual class - only a pointer to a class.

You may have to do something similar in one of the other include files. E.g. in thread.h

    class AddrSpace - instead of including addrspace.h and then
                      include addrspace.h in thread.cc