public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* problems with undefined references
@ 2002-06-25  1:58 Brad Douglas
  2002-06-25 10:04 ` Gokhan Kisacikoglu
  0 siblings, 1 reply; 2+ messages in thread
From: Brad Douglas @ 2002-06-25  1:58 UTC (permalink / raw)
  To: gcc-help

[-- Attachment #1: Type: text/plain, Size: 3484 bytes --]

Hi all,

I'm trying to implement a shared memory manager, and I want to use a singleton class to do so.  I've also create a class to destroy the single instance on process shut down and do the detach and free the shared memory if the process is the last to detach.  I found a good patter to do this using a friend destoyer class as a static data member ala http://lib.stat.cmu.edu/~lamj/sigs/c++-report/cppr9606.c.vlissides.html.  I've cut my code right down to a skeloton that reprodices the error (attached)

I'm getting wierd linker errors saying that the static destroyer class is undefined.... and nm confirms that the reference in Singleton.o is undefined.... but clearly the static reference Singleton::destroyer is defined in the header.

I've had a couple of people to a quick sanity test to see if I've stuffed something obvious and we can't see anything.  If anyone out there in gcc-land can provide some insight I'd be might grateful.

BTW: I'm using gcc 2.96

Here's the output form make:

[xbd@tfsec help]$ make  
-----------------------------------------------------------------------------
Generating: "Singleton.d"    Reason: "Singleton.cpp Makefile"
-----------------------------------------------------------------------------
/usr/bin/gcc -MMD -E -I/scratch/xbd/tflcs/src/include  Singleton.cpp > /dev/null
-----------------------------------------------------------------------------
Building: "Singleton.o",    Reason: "Singleton.cpp Singleton.d Makefile Singleton.h"
-----------------------------------------------------------------------------
/usr/bin/gcc -ggdb -pedantic -Wall -ansi -c -I/scratch/xbd/tflcs/src/include  Singleton.cpp -o Singleton.o
make -C test
make[1]: Entering directory `/scratch/xbd/tflcs/src/util/help/test'
-----------------------------------------------------------------------------
Generating: "SingletonTest.d"    Reason: "SingletonTest.cpp Makefile"
-----------------------------------------------------------------------------
/usr/bin/gcc -MMD -E -I/scratch/xbd/tflcs/src/include -I.. -I../../include SingletonTest.cpp > /dev/null
make[1]: Leaving directory `/scratch/xbd/tflcs/src/util/help/test'
make[1]: Entering directory `/scratch/xbd/tflcs/src/util/help/test'
-----------------------------------------------------------------------------
Building: "SingletonTest.o",    Reason: "SingletonTest.cpp SingletonTest.d Makefile ../Singleton.h"
-----------------------------------------------------------------------------
/usr/bin/gcc -ggdb -pedantic -Wall -ansi -c -I/scratch/xbd/tflcs/src/include -I.. -I../../include SingletonTest.cpp -o SingletonTest.o
SingletonTest.cpp: In function `int main (int, char **)':
SingletonTest.cpp:8: warning: unused variable `Singleton *tmp'
-----------------------------------------------------------------------------
Linking: "SingletonTest",	Reason: "SingletonTest.o Makefile"
-----------------------------------------------------------------------------
/usr/bin/gcc -ggdb -pedantic -Wall -ansi -lstdc++ ../Singleton.o  SingletonTest.o -o SingletonTest
../Singleton.o: In function `Singleton::getInstance(void)':
/scratch/xbd/tflcs/src/util/help/Singleton.cpp:34: undefined reference to `Singleton::destroyer'
collect2: ld returned 1 exit status
make[1]: *** [SingletonTest] Error 1
make[1]: Leaving directory `/scratch/xbd/tflcs/src/util/help/test'
make: *** [test] Error 2



 <<Singleton.cpp>>  <<Singleton.h>>  <<SingletonTest.cpp>> 

[-- Attachment #2: Singleton.cpp --]
[-- Type: application/octet-stream, Size: 1472 bytes --]


#include "Singleton.h"

//=========================================================================
// Singleton class implementation

// only the default constructor is implemented as it is the only constructor
// that will be used so we will not get "undefined references" for the copy
// constructor and assignment operator when linking
//

//-------------------------------------------------------------------------
// initialize the pointer to the single isntance
Singleton* Singleton::instance = 0;


//-------------------------------------------------------------------------
// default constructor (just initialises imlp)
Singleton::Singleton()
{ 
}

//-------------------------------------------------------------------------
// getInstance:
//     if NULL construct the sinle instance, otherwise just return it
Singleton* Singleton::getInstance()
{
    // is it the first call?
    if (instance == 0)
    {
        // create sole instance
        instance = new Singleton;

        destroyer.setSingleton(instance);
    }

    // return the address of sole instance
    return instance;
}

Singleton::~Singleton() 
{
}

//=========================================================================
// SingletonDestroyer class implementation

SingletonDestroyer::~SingletonDestroyer()
{
    delete instance;
}

void SingletonDestroyer::setSingleton( SingletonPtr _instance)
{
    instance = _instance;
}



[-- Attachment #3: Singleton.h --]
[-- Type: application/octet-stream, Size: 2326 bytes --]

// Multiple Inclusion Guard 
#ifndef _SINGLETON 
#define _SINGLETON

//===========================================================================*=
// Singleton class definition
//
//  This object has one purpose: to destroy the single instance of the
//  Singleton on process shutdown.  This is achieved by having a 
//  static destroyer member in in the singleton (static data members are 
//  destroyed as part of process shutdown). 
//
class Singleton;

class SingletonDestroyer
{
    public:
        ~SingletonDestroyer();

        void setSingleton( Singleton * _instance);

    private:
        Singleton * instance;
};

//===========================================================================*=
// Singleton class definition

class Singleton
{

    public:
        //---------------------------------------------------------
        // initialisation / access method 
        static Singleton * getInstance();


    protected:
        //---------------------------------------------------------
        // constructors etc

        // by making the default constructor protected we can enforce
        // the singleton nature, yet still allow derived classes
        Singleton();

        // likewise the copy constructor
        Singleton(const Singleton&);

        // ditto the assignment operator
        Singleton& operator= (const Singleton&);

        //---------------------------------------------------------
        // destructor - we don't want users "deleteing" the refernence
        // they get either
        virtual ~Singleton();    

    private:

        // this is the reference to the single instance of this class
        static Singleton * instance;

        // static members are cleaned on program end so we can create
        // a friend destroyer class to clean up the instance (which will
        // free the shared memory if not other processes are attached
        //
        //  it is essential to destroy the Singleton so that we get
        //  a chance to detach form the shared memory and release it if there
        //  are no other processes attached
        friend class SingletonDestroyer;
        static SingletonDestroyer destroyer;

};
typedef Singleton * SingletonPtr;

#endif  // _SINGLETON


[-- Attachment #4: SingletonTest.cpp --]
[-- Type: application/octet-stream, Size: 182 bytes --]


#include <stdio.h>

#include "Singleton.h"

int main(int argc, char ** argv) {

    SingletonPtr tmp = Singleton::getInstance();

	printf("Hello World\n");
	return 0;
}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: problems with undefined references
  2002-06-25  1:58 problems with undefined references Brad Douglas
@ 2002-06-25 10:04 ` Gokhan Kisacikoglu
  0 siblings, 0 replies; 2+ messages in thread
From: Gokhan Kisacikoglu @ 2002-06-25 10:04 UTC (permalink / raw)
  To: Brad Douglas; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 165 bytes --]

Here I fixed your source code and attached it. You did not declare the
static variable anywhere, it is also safer to call the static variable
with its scope.

Gokhan

[-- Attachment #2: Singleton.cpp --]
[-- Type: text/plain, Size: 1470 bytes --]


#include "Singleton.h"

//=========================================================================
// Singleton class implementation

// only the default constructor is implemented as it is the only constructor
// that will be used so we will not get "undefined references" for the copy
// constructor and assignment operator when linking
//
SingletonDestroyer Singleton :: destroyer;

//-------------------------------------------------------------------------
// initialize the pointer to the single isntance
Singleton* Singleton::instance = 0;


//-------------------------------------------------------------------------
// default constructor (just initialises imlp)
Singleton::Singleton()
{ 
}

//-------------------------------------------------------------------------
// getInstance:
//     if NULL construct the sinle instance, otherwise just return it
Singleton* Singleton::getInstance()
{
    // is it the first call?
    if (instance == 0)
    {
        // create sole instance
        instance = new Singleton;

        Singleton :: destroyer.setSingleton(instance);
    }

    // return the address of sole instance
    return instance;
}

Singleton::~Singleton() 
{
}

//=========================================================================
// SingletonDestroyer class implementation

SingletonDestroyer::~SingletonDestroyer()
{
    delete instance;
}

void SingletonDestroyer::setSingleton( SingletonPtr _instance)
{
    instance = _instance;
}



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-06-25 17:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-25  1:58 problems with undefined references Brad Douglas
2002-06-25 10:04 ` Gokhan Kisacikoglu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).