[xsd-users] Polymorphic problems.

Bill Pringlemeir bpringle at sympatico.ca
Tue Dec 2 11:40:21 EST 2008


On  2 Dec 2008, boris at codesynthesis.com wrote:

> Bill Pringlemeir <bpringle at sympatico.ca> writes:

>> In the type-serializer-map.hxx and type-serializer-map.hxx, there is a
>> map typed to,

>> The &tid is taking a pointer to satisify the 'const type_id*' of the
>> map.  However, the pointer value (memory address) of the typeid(x) is
>> not always binary.  This can be true if different shared libaries are
>> used and the compiler has several RTTI structures for identical type
>> infos.

> The pointers to std::type_info are only used to store references to the
> objects and not to compare them. If you look at the implementation of
> type_id_comparator (passed as the third template argument to std::map),
> you will see that it compares the two objects using the before()
> function provided by type_info:

Right, before fulfills the conditions.  However, there is a hidden
'==' in the find on the primary key which is a pointer.

> This means that even if the type_info object in the map and the one
> passed to find() are different, the map search should still work
> properly (provided the C++ implementation is conformant).

Not really.  It means that the map will construct a tree to find the
non-identical pointers quickly.  If the std::map only uses the
'before' functionality, then how does find() know when it has found an
identical value versus one that is !before() or after?  find must use
the '==' operator on the primary key.  I don't know of a standard, etc
that mentions this, but it *IS* impossible to implement 'find()'
without an operator '==' on the primary key.

>> We are having platform dependent problems with polymorphic
>> serialization and from debugging, this seems to be the problem.

> Which platform is it?

The platform is AIX with xlC.  I do think that someone had posted a
similar problem with Windows DLL's.  They couldn't give you a good
test case and came up with some other work around.

The following test case demonstrates the problem.  This fails on
various versions of gcc.  However for the type-serializer-map.[th]xx
to fail, the platform must have typeid() that return different
pointers.

[start test]
#include <iostream>
#include <map>
#include <string.h>

std::map<char *, std::string> theMap;

struct type_id_comparator
{
    bool
    operator() (const char* x, const char* y) const
        {
            return x < y;
        }
};

int main(void)
{
    char *key1 = "key1";
    char *key2 = "key2";
    char *key3 = "key3";
    char *key4 = "key4";

    theMap.insert(std::make_pair(key1, std::string(key1)));
    theMap.insert(std::make_pair(key2, std::string(key2)));
    theMap.insert(std::make_pair(key3, std::string(key3)));
    theMap.insert(std::make_pair(key4, std::string(key4)));

    char *compare = new char[5];
    strcpy(compare, key1);
        
    if(theMap.find(compare) != theMap.end() )
    {
        std::cout << "We have a match." << std::endl;
    }
    else
    {
        std::cout << "No match." << std::endl;
    }

    if(theMap.find("key1") != theMap.end() )
    {
        std::cout << "We have a match." << std::endl;
    }
    else
    {
        std::cout << "No match." << std::endl;
    }
    
    printf("key1: %p compare: %p value: %p\n", key1, compare, "key1"); 
                                       
    return 0;
}
[end test]

Regards,
Bill Pringlemeir.

-- 
How do we make long-term thinking automatic and common instead of
difficult and rare? - Stewart Brand




More information about the xsd-users mailing list