public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Brad Douglas" <brad.douglas@saabsystems.com.au>
To: <gcc-help@gcc.gnu.org>
Subject: problems with undefined references
Date: Tue, 25 Jun 2002 01:58:00 -0000	[thread overview]
Message-ID: <7DA8A54A920E1441960C129BDDFE4E9A042390@dr-honeydew.saabsystems.com.au> (raw)

[-- 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;
}

             reply	other threads:[~2002-06-25  8:58 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-06-25  1:58 Brad Douglas [this message]
2002-06-25 10:04 ` Gokhan Kisacikoglu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7DA8A54A920E1441960C129BDDFE4E9A042390@dr-honeydew.saabsystems.com.au \
    --to=brad.douglas@saabsystems.com.au \
    --cc=gcc-help@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).