Thread View: comp.std.c++
4 messages
4 total messages
Started by Martin Hitz
Tue, 30 Apr 1991 02:40
backward virtual function call
Author: Martin Hitz
Date: Tue, 30 Apr 1991 02:40
Date: Tue, 30 Apr 1991 02:40
24 lines
884 bytes
884 bytes
I wonder if the following is guaranteed to print 1:
#include <stream.h>
struct X {
virtual f() { return 1; }
};
struct Y : X {
f() { return 2; }
};
main()
{
X x;
Y * y = (Y *) &x;
cout << y->f();
}
The ARM explains the usual case, that a call of f() for an object of
class Y invokes Y::f(), even if it is called via a pointer to X,
but I couldn't find anything about the above case. Zortech and g++
both yield 1 for this example. Is this considered to be the standard
behaviour?
Martin Hitz (hitz@csi.uottawa.ca)
Re: backward virtual function call
Author: William M Miller
Date: Tue, 30 Apr 1991 14:03
Date: Tue, 30 Apr 1991 14:03
30 lines
1465 bytes
1465 bytes
hitz@sim5.csi.uottawa.ca (Martin Hitz) writes:
> struct X {
> virtual f() { return 1; }
> };
> struct Y : X {
> f() { return 2; }
> };
>
> main()
> {
> X x;
> Y * y = (Y *) &x;
> cout << y->f();
> }
>
> The ARM explains the usual case, that a call of f() for an object of
> class Y invokes Y::f(), even if it is called via a pointer to X,
> but I couldn't find anything about the above case.
That's because it's an error. See section 5.4 of E&S: "Such a cast from a
base to a derived class assumes that the object of the base class is a
sub-object of an object of the derived class; the resulting pointer points
to the enclosing object of the derived class. If the object of the base
class is not a sub-object of an object of the derived class, the cast may
cause an exception." In other words, the behavior is undefined, and an
implementation under which the program printed -356, or dumped core, or
erased your disk would be perfectly legitimate.
-- William M. Miller, Glockenspiel, Ltd.
wmm@world.std.com
Re: backward virtual function call
Author: Andrew Koenig
Date: Tue, 30 Apr 1991 21:15
Date: Tue, 30 Apr 1991 21:15
31 lines
1081 bytes
1081 bytes
In article <1991Apr30.024010.4331@csi.uottawa.ca> hitz@sim5.csi.uottawa.ca (Martin Hitz) writes:
> #include <stream.h>
> struct X {
> virtual f() { return 1; }
> };
> struct Y : X {
> f() { return 2; }
> };
> main()
> {
> X x;
> Y * y = (Y *) &x;
> cout << y->f();
> }
The effects of things like this are undefined.
In this particular example, I expect that many implementations
will print 2, but the assignment
Y * y = (Y *) &x;
is well-defined only if &x points at an object of class Y --
which, of course, it does not.
--
--Andrew Koenig
ark@europa.att.com
Re: backward virtual function call
Author: Jim ADCOCK
Date: Mon, 06 May 1991 19:12
Date: Mon, 06 May 1991 19:12
61 lines
1873 bytes
1873 bytes
In article <1991Apr30.024010.4331@csi.uottawa.ca> hitz@sim5.csi.uottawa.ca (Martin Hitz) writes:
|I wonder if the following is guaranteed to print 1:
|
|#include <stream.h>
|struct X {
| virtual f() { return 1; }
|};
|struct Y : X {
| f() { return 2; }
|};
|
|main()
|{
| X x;
| Y * y = (Y *) &x;
| cout << y->f();
|}
|
|The ARM explains the usual case, that a call of f() for an object of
|class Y invokes Y::f(), even if it is called via a pointer to X,
|but I couldn't find anything about the above case. Zortech and g++
|both yield 1 for this example. Is this considered to be the standard
|behaviour?
What would a C++ compiler then do with the following?
[All that I'm aware of act in an ill-defined manner, which is expected
since the ARM prohibits such erroneous down-casts. Your example just
happens to work on most C++ compilers]
extern "C" int printf(const char*, ...);
class A
{
private: virtual void illegalToAccess()
{ printf("erroneous access of A private method\n"); }
public: virtual void print() { printf("A\n"); }
};
class B
{
public: virtual void print() { printf("B\n"); }
private: virtual void illegalToAccess()
{ printf("erroneous access of B private method\n"); }
};
class AB: public A, public B
{
public: virtual void print() { printf("AB\n"); }
};
main()
{
A aA;
B aB;
A* a = &aA;
((AB*)a)->print();
B* b = &aB;
((AB*)b)->print();
return 0;
}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads