Topic: dynamic_cast, typeid, and non-polymorphic types


Author: tony@online.tmx.com.au (Tony Cook)
Date: 1995/08/06
Raw View
Scott Meyers (smeyers@netcom.com) wrote:
: Here's why I care.  I'd like to be able to report on whether a pointer
: was allocated by operator new/new[].  If I make the assumptions that (1)
: everybody uses the operator new/new[] I provide and that (2) the new
: operator returns the same pointer as the underlying call to operator
: new/new[], I believe the following should work:

assumption two will probably not be valid for new[] (as the
implementation may use some space to store the number of elements in
the array).
--
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/08/07
Raw View
Scott Meyers (smeyers@netcom.com) wrote:

|> Here's why I care.  I'd like to be able to report on whether a pointer
|> was allocated by operator new/new[].  If I make the assumptions that (1)
|> everybody uses the operator new/new[] I provide and that (2) the new
|> operator returns the same pointer as the underlying call to operator
|> new/new[], I believe the following should work:

I don't think that you can assume (2), particularly in the case of
new[].  (Typically, the compiler will add a hidden variable in front of
the array, with the number of elements in it.)

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: smeyers@netcom.com (Scott Meyers)
Date: 1995/08/03
Raw View
Can somebody explain why dynamic_cast only works on polymorphic types,
but typeid has no such restriction?  In D/E, Bjarne explains the
restriction on dynamic_cast by saying

  Supporting RTTI for a non-polymorphic type would simply provide
  support for switch-on-type-field programming.  Naturally the language
  should not make that syle impossible, but I saw no need to complicate
  the language solely to accommodate it.

Given that typeid can be used to support switch-on-type programming,
this certainly sounds like another of those cases where an arbitrary
restriction is claimed to be a simplification to the language.

Here's why I care.  I'd like to be able to report on whether a pointer
was allocated by operator new/new[].  If I make the assumptions that (1)
everybody uses the operator new/new[] I provide and that (2) the new
operator returns the same pointer as the underlying call to operator
new/new[], I believe the following should work:

  void * operator new(size_t size)
  {
    void *p = malloc(size);

    // add p to a collection of addresses for single objects

    return p;
  }

  void * operator new[](size_t size)
  {
    void *p = malloc(size);

    // add p to a collection of addresses for arrays

    return p;
  }

  template<class T>
  bool isAHeapObject(const T *addr)
  {
    // DWP 5.2.6, paragraph 7, says that dynamically casting a pointer
    // to cv void* returns a pointer to the complete object, which in this
    // case should be what operator new/new[] returned (if this is a
    // heap-allocated object)
    const void *objectAddress = dynamic_cast<const void*>(addr);

    return (whether objectAddress is in the collection of addresses for
            single objects);
  }

  template<class T>
  bool isAHeapArray(const T *addr)
  {
    const void *objectAddress = dynamic_cast<const void*>(addr);

    return (whether objectAddress is in the collection of addresses for
            arrays);
  }

This fails, because I can't use isAHeapObject or isAHeapArray for
built-in types or for classes with no virtual functions.  I could
specialize the templates for the built-ins, but I'm pretty much out of
luck for classes with no virtual functions.  Sigh.

So I repeat my original question: Can somebody explain why dynamic_cast
only works on polymorphic types, but typeid has no such restriction?

Thanks,

Scott







Author: jason@cygnus.com (Jason Merrill)
Date: 1995/08/03
Raw View
>>>>> Scott Meyers <smeyers@netcom.com> writes:

> Can somebody explain why dynamic_cast only works on polymorphic types,
> but typeid has no such restriction?

Because I don't want to pay for the overhead of storing the necessary
information for non-polymorphic types.  Polymorphic types already have
vtables for this sort of thing.

Jason






Author: vandevod@avs.cs.rpi.edu (David Vandevoorde)
Date: 1995/08/03
Raw View
[ This funny: I just replied to another posting of yours where I could
  only offer an opinion and no solution - here I do the opposite :-) ]
[ Follow-up to comp.lang.c++ ]

In article <smeyersDCpzD0.9wE@netcom.com>,
Scott Meyers <smeyers@netcom.com> wrote:
>Can somebody explain why dynamic_cast only works on polymorphic types,
>but typeid has no such restriction?  In D/E, Bjarne explains the
>restriction on dynamic_cast by saying
[...]
I cannot give any better reason than Bjarne Stroustrup.

>Here's why I care.  I'd like to be able to report on whether a pointer
>was allocated by operator new/new[].  If I make the assumptions that (1)
>everybody uses the operator new/new[] I provide and that (2) the new
>operator returns the same pointer as the underlying call to operator
>new/new[], I believe the following should work:
[ code elided ]
>This fails, because I can't use isAHeapObject or isAHeapArray for
>built-in types or for classes with no virtual functions.  I could
>specialize the templates for the built-ins, but I'm pretty much out of
>luck for classes with no virtual functions.  Sigh.

I'm wondering if you couldn't work the other way: instead of storing
pointers to complete objects and then trying to cast arguments to
complete objects, why not storing pointers to the root-class and
comparing those? It should be slightly more efficient and I think
you can always find the pointer to the base-class.
[...]
>
>Scott
>
 Daveed