473,396 Members | 1,775 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

dynamic_cast<> perfomans

Hello.

Returning to question of manual class type identification, tell me, for
ordinary inheritance is C++ garantee that

dynamic_cast<Derived*>(Base*)

can be implemented similarly to

return (Base*->type_fild >= Derived_typeid)? Base*: 0;

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 13 '07 #1
15 2789
* Grizlyk:
Hello.

Returning to question of manual class type identification, tell me, for
ordinary inheritance is C++ garantee that

dynamic_cast<Derived*>(Base*)
That's not valid C++ syntax. The argument must be a value, not a type.

can be implemented similarly to

return (Base*->type_fild >= Derived_typeid)? Base*: 0;
Ditto.

But if I understand you correctly you're wondering whether every node
in a tree (nodes corresponding to classes) can be assigned a number such
that NumberOf(A) >= NumberOf(B) implies that A is a parent node of B or
equal to B.

And the answer to that is no, because two unrelated nodes would have to
have either equal numbers (incorrectly implying they're the same) or
unequal numbers (incorrectly implying one is a parent node of the other).

However, the parent-child relationships can be represented as a matrix.

Which means that if you replace '>=' with a matrix lookup you can do it.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 13 '07 #2
"Grizlyk" <gr******@yandex.ruwrote in news:eq**********@aioe.org:
Hello.

Returning to question of manual class type identification, tell me, for
ordinary inheritance is C++ garantee that

dynamic_cast<Derived*>(Base*)

can be implemented similarly to

return (Base*->type_fild >= Derived_typeid)? Base*: 0;
Please use real code to express what you're trying to accomplish. And even
then, your pseudo code is still wrong. The pointer that you can get back
from dynamic_cast can be something other than pointerToBase and 0.
I guess the other question, is why would you want to? What's wrong with
dynamic_cast ?
Feb 13 '07 #3

Alf P. Steinbach wrote:
>* Grizlyk:
>Hello.

Returning to question of manual class type identification, tell me, for
ordinary inheritance is C++ garantee that

dynamic_cast<Derived*>(Base*)

That's not valid C++ syntax. The argument must be a value, not a type.
it is pseudo code containing only types to cast.
>
>can be implemented similarly to

return (Base*->type_fild >= Derived_typeid)? Base*: 0;

Ditto.
The same plus members "type_fild" & "Derived_typeid"
But if I understand you correctly you're wondering whether every node in a
tree (nodes corresponding to classes) can be assigned a number such that
NumberOf(A) >= NumberOf(B) implies that A is a parent node of B or equal
to B.

And the answer to that is no, because two unrelated nodes would have to
have either equal numbers (incorrectly implying they're the same) or
unequal numbers (incorrectly implying one is a parent node of the other).
The question is "if no that how"? How it must be implemented (recomended by
C++ standard) to save space and high perfomance? It is importan to me - is
C++ garantee the time of dynamic_cast<in the case of ordinary inheritance
is equal to one-two pseudo expression "if-else"

return (Base*->type_fild >= Derived*->type_fild)? Base*: 0;

or not?

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 13 '07 #4

Andre Kostur wrote:
>>
Returning to question of manual class type identification, tell me, for
ordinary inheritance is C++ garantee that

dynamic_cast<Derived*>(Base*)

can be implemented similarly to

return (Base*->type_fild >= Derived_typeid)? Base*: 0;

Please use real code to express what you're trying to accomplish. And
even
then, your pseudo code is still wrong. The pointer that you can get back
from dynamic_cast can be something other than pointerToBase and 0.
see message above - my answer to "Alf P. Steinbach"

I guess the other question, is why would you want to? What's wrong with
dynamic_cast ?
I always found "dynamic_cast" in my classes, it is suitable for some cases
and i want to know cost (time&size) of the cast.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 13 '07 #5
Grizlyk wrote:
>
Alf P. Steinbach wrote:
>>* Grizlyk:
>>Hello.

Returning to question of manual class type identification, tell me, for
ordinary inheritance is C++ garantee that

dynamic_cast<Derived*>(Base*)

That's not valid C++ syntax. The argument must be a value, not a type.

it is pseudo code containing only types to cast.
>>
>>can be implemented similarly to

return (Base*->type_fild >= Derived_typeid)? Base*: 0;

Ditto.

The same plus members "type_fild" & "Derived_typeid"
>But if I understand you correctly you're wondering whether every node in
a tree (nodes corresponding to classes) can be assigned a number such
that NumberOf(A) >= NumberOf(B) implies that A is a parent node of B or
equal to B.

And the answer to that is no, because two unrelated nodes would have to
have either equal numbers (incorrectly implying they're the same) or
unequal numbers (incorrectly implying one is a parent node of the other).

The question is "if no that how"? How it must be implemented (recomended
by C++ standard) to save space and high perfomance?
The standard gives no hints as to how dynamic_cast<is to be implemented
(there is no recommended implementation); and neither does it give any
guarantees as to performance.

It is importan to me -
is C++ garantee the time of dynamic_cast<in the case of ordinary
inheritance is equal to one-two pseudo expression "if-else"

return (Base*->type_fild >= Derived*->type_fild)? Base*: 0;

or not?
In which way is this information important to you?
Best

Kai-Uwe Bux
Feb 13 '07 #6
Grizlyk wrote:
I always found "dynamic_cast" in my classes, it is suitable for some cases
and i want to know cost (time&size) of the cast.
If you want to know the overhead of dynamic_cast on your compiler, you will
have to look at what it actually makes out of it, not at how it might in
theory be implemented.

Feb 13 '07 #7

Kai-Uwe Bux wrote:
>>
>>But if I understand you correctly you're wondering whether every node in
a tree (nodes corresponding to classes) can be assigned a number such
that NumberOf(A) >= NumberOf(B) implies that A is a parent node of B or
equal to B.

And the answer to that is no, because two unrelated nodes would have to
have either equal numbers (incorrectly implying they're the same) or
unequal numbers (incorrectly implying one is a parent node of the
other).

The question is "if no that how"? How it must be implemented (recomended
by C++ standard) to save space and high perfomance?

The standard gives no hints as to how dynamic_cast<is to be implemented
(there is no recommended implementation); and neither does it give any
guarantees as to performance.
>It is important to me -
does C++ garantee the time of dynamic_cast<in the case of ordinary
inheritance is equal to one-two pseudo expression "if-else"

return (Base*->type_fild >= Derived*->type_fild)? Base*: 0;

or not?

In which way is this information important to you?
1.
The dynamic_cast<is required by design, because I can not define huge base
class interface but simple interface is not enough to possible derived.

The solution for possible manual replacement of dynamic_cast in the case of
ordinary inheritance came up to my mind, assuming that C++ will do nothing
for perfomance here.

Consider:

Let each derived from first underived base have unique number. But we no
need number, we can use single bit in bitmask

Base->Derived_A1->Derived_B1->Derived_C1->Derived_E1
Base->Derived_A1->Derived_B2->Derived_C2->Derived_E2

[class] [type] [mask]

Base 0x0001 0x0001
Derived_A1 0x0003 0x0002
#
Derived_B1 0x0007 0x0004
Derived_C1 0x000F 0x0008
Derived_E1 0x001F 0x0010
#
Derived_B2 0x0023 0x0020
Derived_C2 0x0063 0x0040
Derived_E2 0x00E3 0x0080

dynamic_cast<>() can be implemented as single if-else operator

//extern Base* ptr;
//int Derived_C1::mask==0x0008;
//dynamic_cast<Derived_C1*>(ptr)
return ( ptr->type & Derived_C1::mask )?
reinterpret_cast<Derived_C1*>(ptr):
0;

The condition is true only if ptr is Derived_C1 or Derived_E1

2.
The 32 bit unsigned can represent 32 distinct class. But fortunatelly, we no
need cast to each derived class, not each class is declaration of uniq
interface.

New interfaces are quite rare declared so 32 bits is enough, but we can use
64 bits and two if-else operators.

All code listed below compiler easy can do itself if programmer could tell
to compiler that class declaration is new interface declaration with the
help of new keyword "interface" and "interface_cast" instead of
dynamic_cast.

Let we have several classes as declarations of base interface extentions in
the inheritance tree. Consider the following example (cut&paste it into
file):

-- cut here --
/*
Base->Derived_A1->Derived_B1->Derived_C1->Derived_E1
ITF0-NOT_ITF ITF1->

Base->Derived_A1->Derived_B2->Derived_C2->Derived_E2
ITF2->

Base->Derived_A1->Derived_B2->Derived_C3->Derived_E3
ITF2- NOT_ITF

Derived_C3->Derived_E4
Derived_C3->Derived_E5
Derived_C3->Derived_E6
[class] [type] [mask]

Base 0x0001 0x0001 ITF0
Derived_B1 0x0003 0x0002 ITF1
Derived_B2 0x0005 0x0004 ITF2

*/

#include <stdio.h>

typedef unsigned uint;
//C++ do not support
#define interface

//******************
//ITF0
//******************
class Base interface
{
protected:
static uint type;

public:
virtual uint itype()const {return type;}

enum { _type=0x0001 };
enum { mask=0x0001 };
};

class Derived_A1: public Base {};

//******************
//ITF1
//******************
class Derived_B1 interface: public Derived_A1
{
protected:
static uint type;

public:
uint itype()const {return type;}

enum { _type=0x0003 };
enum { mask=0x0002 };
};

class Derived_C1: public Derived_B1 {};
class Derived_E1: public Derived_C1 {};

//******************
//ITF2
//******************
class Derived_B2 interface: public Derived_A1
{
protected:
static uint type;

public:
uint itype()const {return type;}

enum { _type=0x0005 };
enum { mask=0x0004 };
};

class Derived_C2: public Derived_B2 {};
class Derived_E2: public Derived_C2 {};

class Derived_C3: public Derived_B2 {};
class Derived_E3: public Derived_C3 {};
class Derived_E4: public Derived_C3 {};
class Derived_E5: public Derived_C3 {};
class Derived_E6: public Derived_C3 {};

//******************
//interface_cast
//******************
template<class Tdst,class Tsrc>
Tdst* interface_cast(Tsrc* ptr)
{
fprintf(stderr,"src: %u, dst: %u, &=%u\n", ptr->itype(), Tdst::mask,
(ptr->itype()&Tdst::mask) );
return ( ptr->itype() & Tdst::mask )?
reinterpret_cast<Tdst*>(ptr):
0;
}

//******************
//******************
uint Base::type=Base::_type;
uint Derived_B1::type=Derived_A1::_type;
uint Derived_B2::type=Derived_B2::_type;

Derived_E1 *e1=0;
Derived_E3 *e3=0;

int main()
{
Base *base=new Derived_E2;
printf("%s[%p]\n","Derived_E2",base);

e1=interface_cast<Derived_E1,Base>(base);
printf("%s[%p]->%s[%p]\n","Base",base,"Derived_E1",e1);

e3=interface_cast<Derived_E3,Base>(base);
printf("%s[%p]->%s[%p]\n","Base",base,"Derived_E3",e3);

Base *const tmp=base;
base=interface_cast<Base,Derived_E3>(e3);
printf("%s[%p]->%s[%p]\n","Derived_E3",tmp,"Base",base);

}

-- cut here --

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 13 '07 #8
Grizlyk wrote:
>
Kai-Uwe Bux wrote:
>>>
But if I understand you correctly you're wondering whether every node
in a tree (nodes corresponding to classes) can be assigned a number
such that NumberOf(A) >= NumberOf(B) implies that A is a parent node of
B or equal to B.

And the answer to that is no, because two unrelated nodes would have to
have either equal numbers (incorrectly implying they're the same) or
unequal numbers (incorrectly implying one is a parent node of the
other).

The question is "if no that how"? How it must be implemented (recomended
by C++ standard) to save space and high perfomance?

The standard gives no hints as to how dynamic_cast<is to be implemented
(there is no recommended implementation); and neither does it give any
guarantees as to performance.
>>It is important to me -
does C++ garantee the time of dynamic_cast<in the case of ordinary
inheritance is equal to one-two pseudo expression "if-else"

return (Base*->type_fild >= Derived*->type_fild)? Base*: 0;

or not?

In which way is this information important to you?

1.
The dynamic_cast<is required by design, because I can not define huge
base class interface but simple interface is not enough to possible
derived.

The solution for possible manual replacement of dynamic_cast in the case
of ordinary inheritance came up to my mind, assuming that C++ will do
nothing for perfomance here.
Don't assume! Measure! You may want to google "premature optimization".

>
Consider:
Ok.
Let each derived from first underived base have unique number. But we no
need number, we can use single bit in bitmask

Base->Derived_A1->Derived_B1->Derived_C1->Derived_E1
Base->Derived_A1->Derived_B2->Derived_C2->Derived_E2

[class] [type] [mask]

Base 0x0001 0x0001
Derived_A1 0x0003 0x0002
#
Derived_B1 0x0007 0x0004
Derived_C1 0x000F 0x0008
Derived_E1 0x001F 0x0010
#
Derived_B2 0x0023 0x0020
Derived_C2 0x0063 0x0040
Derived_E2 0x00E3 0x0080

dynamic_cast<>() can be implemented as single if-else operator

//extern Base* ptr;
//int Derived_C1::mask==0x0008;
//dynamic_cast<Derived_C1*>(ptr)
return ( ptr->type & Derived_C1::mask )?
reinterpret_cast<Derived_C1*>(ptr):
0;

The condition is true only if ptr is Derived_C1 or Derived_E1

2.
The 32 bit unsigned can represent 32 distinct class. But fortunatelly, we
no need cast to each derived class, not each class is declaration of uniq
interface.

New interfaces are quite rare declared so 32 bits is enough, but we can
use 64 bits and two if-else operators.

All code listed below compiler easy can do itself if programmer could tell
to compiler that class declaration is new interface declaration with the
help of new keyword "interface" and "interface_cast" instead of
dynamic_cast.

Let we have several classes as declarations of base interface extentions
in the inheritance tree. Consider the following example (cut&paste it into
file):

-- cut here --
/*
Base->Derived_A1->Derived_B1->Derived_C1->Derived_E1
ITF0-NOT_ITF ITF1->

Base->Derived_A1->Derived_B2->Derived_C2->Derived_E2
ITF2->

Base->Derived_A1->Derived_B2->Derived_C3->Derived_E3
ITF2- NOT_ITF

Derived_C3->Derived_E4
Derived_C3->Derived_E5
Derived_C3->Derived_E6
[class] [type] [mask]

Base 0x0001 0x0001 ITF0
Derived_B1 0x0003 0x0002 ITF1
Derived_B2 0x0005 0x0004 ITF2

*/

#include <stdio.h>

typedef unsigned uint;
//C++ do not support
#define interface

//******************
//ITF0
//******************
class Base interface
{
protected:
static uint type;

public:
virtual uint itype()const {return type;}

enum { _type=0x0001 };
enum { mask=0x0001 };
};

class Derived_A1: public Base {};

//******************
//ITF1
//******************
class Derived_B1 interface: public Derived_A1
{
protected:
static uint type;

public:
uint itype()const {return type;}

enum { _type=0x0003 };
enum { mask=0x0002 };
};

class Derived_C1: public Derived_B1 {};
class Derived_E1: public Derived_C1 {};

//******************
//ITF2
//******************
class Derived_B2 interface: public Derived_A1
{
protected:
static uint type;

public:
uint itype()const {return type;}

enum { _type=0x0005 };
enum { mask=0x0004 };
};

class Derived_C2: public Derived_B2 {};
class Derived_E2: public Derived_C2 {};

class Derived_C3: public Derived_B2 {};
class Derived_E3: public Derived_C3 {};
class Derived_E4: public Derived_C3 {};
class Derived_E5: public Derived_C3 {};
class Derived_E6: public Derived_C3 {};

//******************
//interface_cast
//******************
template<class Tdst,class Tsrc>
Tdst* interface_cast(Tsrc* ptr)
{
fprintf(stderr,"src: %u, dst: %u, &=%u\n", ptr->itype(), Tdst::mask,
(ptr->itype()&Tdst::mask) );
return ( ptr->itype() & Tdst::mask )?
reinterpret_cast<Tdst*>(ptr):
You need a static_cast<or a dynamic_cast<here. Otherwise, you invite
undefined behavior of the _serious_ sort: in the case of multiple
inheritance, casting pointers up and down really does change bit-patterns
and reinterpret_cast<is not required to do anything like that for you.
(Of course, the return value is formally unspecified even in the case of
single inheritance.)

0;
}

//******************
//******************
uint Base::type=Base::_type;
uint Derived_B1::type=Derived_A1::_type;
uint Derived_B2::type=Derived_B2::_type;

Derived_E1 *e1=0;
Derived_E3 *e3=0;

int main()
{
Base *base=new Derived_E2;
printf("%s[%p]\n","Derived_E2",base);

e1=interface_cast<Derived_E1,Base>(base);
printf("%s[%p]->%s[%p]\n","Base",base,"Derived_E1",e1);

e3=interface_cast<Derived_E3,Base>(base);
printf("%s[%p]->%s[%p]\n","Base",base,"Derived_E3",e3);

Base *const tmp=base;
base=interface_cast<Base,Derived_E3>(e3);
printf("%s[%p]->%s[%p]\n","Derived_E3",tmp,"Base",base);

}

-- cut here --

Interesting idea. However, seems to make code more difficult to maintain
since you have to implement you own mechanism keeping track of the
inheritance hierarchy.

Now you should measure whether a correct version (e.g., using static_cast<>)
buys you anything in terms of speed.
Best

Kai-Uwe Bux
Feb 13 '07 #9
Kai-Uwe Bux wrote:
>>
//C++ do not support
#define interface

//******************
//ITF0
//******************
class Base interface
{
protected:
static uint type;

public:
virtual uint itype()const {return type;}

enum { _type=0x0001 };
enum { mask=0x0001 };
};
//******************
//interface_cast
//******************
template<class Tdst,class Tsrc>
Tdst* interface_cast(Tsrc* ptr)
{
fprintf(stderr,"src: %u, dst: %u, &=%u\n", ptr->itype(), Tdst::mask,
(ptr->itype()&Tdst::mask) );
return ( ptr->itype() & Tdst::mask )?
reinterpret_cast<Tdst*>(ptr):

You need a static_cast<or a dynamic_cast<here. Otherwise, you invite
undefined behavior of the _serious_ sort: in the case of multiple
inheritance, casting pointers up and down really does change bit-patterns
and reinterpret_cast<is not required to do anything like that for you.
(Of course, the return value is formally unspecified even in the case of
single inheritance.)
The dynamic_cast<can not be used because we are making replacement for
dynamic_cast<>.

Also we are assuming case of ordinary inheritance.

Also real class of object "*ptr" is completely defined by bit-pattern so if
condition (ptr->itype()&Tdst::mask) is true, then "*ptr" is object of "Tdst"
class, so reinterpret_cast<Tdst*is what we need here - no surprises -
address change its type to correct and I am not sure that static_cast<will
do the same here.

Real problem here that we have no compiler support. So we must make the
bit-patterns and create data manualy, like this
>protected:
static uint type;

public:
virtual uint itype()const {return type;}

enum { _type=0x0001 };
enum { mask=0x0001 };
>uint Base::type=Base::_type;
and we can not control at compile time that interface_cast obtain as DST
class have declared as "interface". It is ecidently, that interface_cast can
cast only classes declared as "interface".

Yes, you do not detect some hard errors in the code, for example, here
> e1=interface_cast<Derived_E1,Base>(base);
Derived_E1 is not interface, but interface_cast can cast only to interface.
I can of course, include NOT_ITF bit and detect errors at runtime, but it is
not so good as compile time.

By the way, the cast could be done without new keyword "interface_cast<>" by
"static_cast<Tdst*>(ptr)" and compiler can test at compile time that "Tdst"
is declared as "interface" and "ptr" is base for ordinary on the distance
inherited "Tdst".

But new keyword "interface_cast<>" explicit tells to compiler what to do and
especially static_cast<assuming compile time casting, not runtime. Maybe
dynamic_cast<can be used, but dynamic_cast<is for MI purpose and to cast
to cncrete class, not interface.
Also it is easy to do unlimited number of inherited classes, reserving
bit-patterns

0x00000000 - not interface NOT_ITF
0xFFFFFFFF - to cast use next fild

and compiler can generate inline interface_cast
- one-if-else for number of inherited interfaces less then 32,
- two-if-else for number of inherited interfaces less then 63,
and so on, but mostly we have no more than 10-20 interfaces, inherited from
one base, so one-if-else cast will be generated.
>
> 0;
}

//******************
//******************
uint Base::type=Base::_type;
uint Derived_B1::type=Derived_A1::_type;
uint Derived_B2::type=Derived_B2::_type;

Derived_E1 *e1=0;
Derived_E3 *e3=0;

int main()
{
Base *base=new Derived_E2;
printf("%s[%p]\n","Derived_E2",base);

e1=interface_cast<Derived_E1,Base>(base);
printf("%s[%p]->%s[%p]\n","Base",base,"Derived_E1",e1);

e3=interface_cast<Derived_E3,Base>(base);
printf("%s[%p]->%s[%p]\n","Base",base,"Derived_E3",e3);

Base *const tmp=base;
base=interface_cast<Base,Derived_E3>(e3);
printf("%s[%p]->%s[%p]\n","Derived_E3",tmp,"Base",base);

}

-- cut here --


Interesting idea. However, seems to make code more difficult to maintain
since you have to implement you own mechanism keeping track of the
inheritance hierarchy.
Keeping track of the interfaces inheritance hierarchy.

Now you should measure whether a correct version (e.g., using
static_cast<>)
buys you anything in terms of speed.
There is nothing measure here. Because static_cast<is ambiguous here. I
agree, that expression

Base *base=new Derived_E2;
e1=static_cast<Derived_E1*>(base);

is silently casted by compiler, but it is wrong, because Derived_E2 and
Derived_E1 has incompatible interfases.

Base->Derived_A1->Derived_B1->Derived_C1->Derived_E1
ITF0-NOT_ITF ITF1->
Derived_B2->Derived_C2->Derived_E2
ITF2->

The classes have diffrents number of functions, diffrents sizeof() and so
on. It is really different classes, in spite of they have common bases
"Base" and "Derived_A1". The diffrences started at Derived_Bx point.

It seems to me, we need apply dynamic_cast<instead of static_cast<when
object, pointer to base class point to, is unknown at compile time. Probably
compiler can not know what kind of pointer used as "ptr" during
static_cast<>(ptr).

The dynamic_cast<will return zero here

Base *base=new Derived_E2;
e1=dynamic_cast<Derived_E1*>(base);

but static cast not.

As for dynamic_cast<>, that I want to have correct runtime cast at the speed
as compile time cast, and dynamic_cast<can not do it at least because
dynamic_cast<is function and have

pushl $0
pushl $__ZTI10Derived_E1
pushl $__ZTI4Base
pushl %ebx
call ___dynamic_cast
addl $20, %esp
ret

___dynamic_cast:
enter
leave
ret

It is overhead in comparison with static_cast<that do nothing or with
interface_cast<that do
call virtual ptr->itype()
cmp
jmp

and I even do not whant to see what is placed between dynamic_cast<>
enter
leave

because it is more then
cmp
jmp

By the way, "virtual uint itype()const" can be replaced to increase cast
speed by non-statatic uint member, so each object of the class will contain
typeid bit-pattern. In the case differences between static_cast<and
interface_cast<will be
mov
cmp
jmp

that more than good for runtime casting.

I think I will add the stuff to my programs, while C++ can not do it.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 14 '07 #10
* Grizlyk:
>
The dynamic_cast<can not be used because we are making replacement for
dynamic_cast<>.
Sorry for butting in, but you sound like a troll: you haven't specified
your requirements.

Let's see,
"In thi world of fairy tales rolls are liked olso"
Yup, a troll.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 14 '07 #11
Grizlyk wrote:
Kai-Uwe Bux wrote:
>>>
//C++ do not support
#define interface

//******************
//ITF0
//******************
class Base interface
{
protected:
static uint type;

public:
virtual uint itype()const {return type;}

enum { _type=0x0001 };
enum { mask=0x0001 };
};
//******************
//interface_cast
//******************
template<class Tdst,class Tsrc>
Tdst* interface_cast(Tsrc* ptr)
{
fprintf(stderr,"src: %u, dst: %u, &=%u\n", ptr->itype(), Tdst::mask,
(ptr->itype()&Tdst::mask) );
return ( ptr->itype() & Tdst::mask )?
reinterpret_cast<Tdst*>(ptr):

You need a static_cast<or a dynamic_cast<here. Otherwise, you invite
undefined behavior of the _serious_ sort: in the case of multiple
inheritance, casting pointers up and down really does change bit-patterns
and reinterpret_cast<is not required to do anything like that for you.
(Of course, the return value is formally unspecified even in the case of
single inheritance.)

The dynamic_cast<can not be used because we are making replacement for
dynamic_cast<>.
Agreed.
Also we are assuming case of ordinary inheritance.

Also real class of object "*ptr" is completely defined by bit-pattern so
if condition (ptr->itype()&Tdst::mask) is true, then "*ptr" is object of
"Tdst" class, so reinterpret_cast<Tdst*is what we need here - no
surprises - address change its type to correct and I am not sure that
static_cast<will do the same here.
Your remarks in defense of reinterpret_cast<are besides the technical
point. You are plain wrong about the behavior of reinterpret_cast<and
static_cast<>. Please refer to the standard, [5.2.9/8-9] and [5.2.10].
Best

Kai-Uwe Bux
Feb 14 '07 #12
RJH
Reading his posts make my eyes bleed.

Feb 15 '07 #13
RJH
On Feb 13, 7:58 pm, "Alf P. Steinbach" <a...@start.nowrote:
* Grizlyk:
The dynamic_cast<can not be used because we are making replacement for
dynamic_cast<>.

Sorry for butting in, but you sound like a troll: you haven't specified
your requirements.

Let's see,
"In thi world of fairy tales rolls are liked olso"

Yup, a troll.

Can someone tell me what that means? Im itching to figure it out.

Feb 15 '07 #14

RJH wrote:
>
Reading his posts make my eyes bleed.
I think the page
http://www.parashift.com/c++-faq-lite/how-to-post.html

and the message (search the group)
===Welcome to comp.lang.c++! Read this first.

can help you to post in the group next time.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 15 '07 #15

RJH wrote:
>>
The dynamic_cast<can not be used because we are making replacement
for
dynamic_cast<>.

Sorry for butting in, but you sound like a troll: you haven't specified
your requirements.

Let's see,
"In thi world of fairy tales rolls are liked olso"

Yup, a troll.


Can someone tell me what that means? Im itching to figure it out.
I think the page
http://www.parashift.com/c++-faq-lite/how-to-post.html

and the message (search the group)
===Welcome to comp.lang.c++! Read this first.

can help you (and "Alf P. Steinbach" also) to post in the group next time.

--
Maksim A. Polyanin

"In thi world of fairy tales rolls are liked olso"
/Gnume/

Feb 15 '07 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: alg | last post by:
dynamic_cast<> comes in play when to perform conversion from a pointer to a base class to a pointer to a derived class. I don't understand: 1. why this is so necessary since we can either use...
11
by: Jamie Burns | last post by:
Hello, I just did a simple benchmark: for (xx=0;xx<100000;xx++) { rDerived* derived = dynamic_cast<rDerived*>(object); if (derived) derived->setValue(message.data.messageSetInt.value); } ...
13
by: baltasarq | last post by:
Hi, there ! When I use dynamic_cast for a single object, I do something like: void foo(Base *base) { if ( dynamic_cast<Derived *>( base ) != NULL ) { ((Derived *) base)->do_something() } }
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.