I'm having trouble producing a test case that causes this problem 
(I'm trying to narrow down a complex case that I have from copyrighted 
code that I can't send out), but the general case is that I have a 
parent template class that is a map.  It defines virtual methods for 
things like its hash function.

   Then, there is a subclass that partially resolves the template to 
have 'const char *' for keys and also defines the virtual methods 
(including the hash method).  The subclass header also has an inline 
definition of the virtual hash function.

   Now, when I go to do a lookup, I crash in some code that looks like 
it is trying to load a function pointer from a vtable (but presumably 
there isn't any vtable due to all the virtual methods being inlined).

   I'm attaching a simplified version of the code that I'd hoped would 
reproduce the problem, but doesn't (just to clarify what I'm talking 
about).

   Before I spend a bunch of time tracking this down -- is this a known 
problem?  Can anyone suggest a workaround ... maybe I can make all the 
virtual methods non-inline, but I'm not convinced of that since it may 
not be able to compile the code w/o knowing all the types involved (I'm 
not a C++ expert by any stretch).


   I'm building my test case as follows (which corresponds to who my 
real case is being build)

/usr/bin/gcc3  -c -x c++ -O0 -fno-inline-functions -Wall -DDEBUG -g 
test.h  -o /tmp/dummy --dump-pch test-ppc.pfe
c++ -O0 -fno-inline-functions -Wall -DDEBUG -g --load-pch test-ppc.pfe 
test.cpp -o test

#ifndef __TEST_H__
#define __TEST_H__

#include <stdio.h>

//
// Map
//

template <class TKEY, class TVAL> class Map
{
public:
    Map();
    virtual ~Map();
    bool get(TKEY key, TVAL& val) const;
protected:
        virtual unsigned int KeyToHashIndex(TKEY key) const;
};

template <class TKEY, class TVAL> inline
bool Map<TKEY, TVAL>::get(TKEY key, TVAL& val) const
{
    unsigned int uiIndex = KeyToHashIndex(key);
    fprintf(stderr, "uiIndex = 0x%08x\n", uiIndex);
    return false;
}

template <class TKEY, class TVAL> inline
Map<TKEY, TVAL>::Map()
{
}
//---------------------------------------------------------------------------
template <class TKEY, class TVAL> inline
Map<TKEY, TVAL>::~Map()
{
}

template <class TKEY, class TVAL> inline
unsigned int Map<TKEY, TVAL>::KeyToHashIndex(TKEY key) const
{
    return 0xdeadbeef;
}

//
// StringMap
//

template <class TVAL> class StringMap : public Map<const char *, TVAL>
{
public:
    StringMap();
    virtual ~StringMap();

protected:
        virtual unsigned int KeyToHashIndex(const char* pcKey) const;
};


template <class TVAL> inline
StringMap<TVAL>::StringMap() :
Map<const char*, TVAL>()
{
}

template <class TVAL> inline
StringMap<TVAL>::~StringMap()
{
}

template <class TVAL> inline
unsigned int StringMap<TVAL>::KeyToHashIndex (const char* pKey) const
{
    return 0xcafefeed;
}

#endif // __TEST_H__
#include "test.h"

int main(int argc, char *argv[])
{
    StringMap<int> x;

    int val;
    const char *key = "";

    x.get(key, val);
    return 0;
}


-tim

Reply via email to