Topic: automatic downcast support through function parameters
Author: danielgutson@hotmail.com (danielgutson@hotmail.com)
Date: Wed, 15 Jan 2003 18:27:58 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0301071313.88d2480@posting.google.com>...
Hello Alan:
First, I'm afraid that virtual functions can only be member functions,
as far as there is a 'virtual table OF a class' (there are no 'global'
virtual tables).
(I strongly suggest to compile or test your code before posting).
Second, I'm not trying to do anything similar with virtual functions,
just hold abstraction of the received parameter:
a function receives an 'upcasted' parameter (contravariant), ignoring
the original derived class, and simply recover it when used.
As many people posted in this thread, RTTI is needed.
They are also right about compiling units: the linker should solve
this.
Finally, the Visitor pattern does not apply to this situation.
regards,
Daniel.
> > > danielgutson@hotmail.com wrote:
> > > > People: I'd like to ask about the feasibility of this:
> > > > automatic downcast during function calls.
> > > > let's have:
> > > > struct Base{};
> > > > struct Der : Base{};
> > > >
> > > > void g(Base* b);
> > > > void g(Der* d);
> > > >
> > > > void f(upcasted Base* b) // see below
> > > > {
> > > > g(b);
> > > > }
> > > >
> > > > void main(void)
> > > > {
> > > > Der d;
> > > > f(&d);
> > > > }
> > > >
> > > > - The idea here is that f ignores the function that will be finally
> > > > invoked, but knows that the pointer was upcasted ('upcasted'
> > > > keyword).
> > > > Then, the function accepting the most derived class (closest to the
> > > > original type) will be invoked, in this case: g(Der*).
> > > >
> > > > The 'spirit' of this is to recover specificity: in the process flow:
> > > > main -> f -> g
> > > > specificity(main) = specificity(g) > specificity(f)
> > > > and this would be an automatic way of recoviring specificity at g,
> > > > without loosing generality at f.
> > > >
> > > > What you think?
>
> > Daniel.Miller@tellabs.com ("Dan'l Miller") wrote
> something about global flow analysis, which misses the point.
>
> > I'm talking ... a kind of condition using RTTI.
> ...
> > can be achieved using a reduced set of RTTI primitives. I think, that
> ...
> > just with some additional entry in the v-table.
>
> Basically you want to do with free functions, the same thing that is
> done with virtual functions. I think another thing that would accomplish
> what you want is to move virtual functions out of the class definition:
>
> struct Base {};
> struct Der : public Base {};
> virtual void g(Base*) { std::cout << "g(Base*)"; }
> virtual void g(Der*) { std::cout << "g(Der *)"; }
> void callg(Base*b) { g(b); }
> int main() {
> Base b; callg(&b); // Displays "g(Base*)"
> Der d; callg(&d); // Displays "g(Der *)"
> }
>
> Consider refactoring your code. If possible, put a member function in
> Base and Der that simply call g() as appropriate. Works today, without
> any changes to the language.
>
> struct Base {
> virtual void callg() { g(this); }
> };
> struct Der : public Base {
> virtual void callg() { g(this); }
> };
> virtual void g(Base*) { std::cout << "g(Base*)"; }
> virtual void g(Der*) { std::cout << "g(Der *)"; }
> void callg(Base*b) { b->callg(); }
> int main() {
> Base b; callg(&b); // Displays "g(Base*)"
> Der d; callg(&d); // Displays "g(Der *)"
> }
>
> You might also want to examine the Visitor pattern for a more
> general-purpose solution to this same problem.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 17 Jan 2003 00:23:54 +0000 (UTC) Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) wrote
> allan_w@my-dejanews.com (Allan W) wrote
>
> Hello Alan:
Allan.
> First, I'm afraid that virtual functions can only be member functions,
> as far as there is a 'virtual table OF a class' (there are no 'global'
> virtual tables).
> (I strongly suggest to compile or test your code before posting).
I accidentally left the word "virtual" in the two free-standing
functions. I also used the wrong notation for calling "callg."
Try this version, which may do what you want without any language
changes:
> > struct Base {
~Base();
> > virtual void callg() { g(this); }
> > };
> > struct Der : public Base {
> > virtual void callg() { g(this); }
> > };
void g(Base*) { std::cout << "g(Base*)"; }
void g(Der*) { std::cout << "g(Der *)"; }
> > void callg(Base*b) { b->callg(); }
> > int main() {
Base *b = new Base;
Base *d = new Der;
//g(*d) would call the wrong version, but callg() figures it out:
b->callg(); // Displays "g(Base*)"
d->callg(); // Displays "g(Der *)"
delete b;
delete d;
> > }
> Second, I'm not trying to do anything similar with virtual functions,
> just hold abstraction of the received parameter:
> a function receives an 'upcasted' parameter (contravariant), ignoring
> the original derived class, and simply recover it when used.
> As many people posted in this thread, RTTI is needed.
> They are also right about compiling units: the linker should solve
> this.
I'm trying to show that you can accomplish the same thing today, without
a language change ('upcasted parameter'). Once you've called the right
virtual function (in this case callg()), the virtual function "knows" the
right type and can call the correct free-standing function (g).
> Finally, the Visitor pattern does not apply to this situation.
I didn't think it would, directly. I just meant that you could
apply some of the same principals to call the correct code
depending on what data type was used.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 8 Jan 2003 05:55:18 +0000 (UTC) Raw View
> > danielgutson@hotmail.com wrote:
> > > People: I'd like to ask about the feasibility of this:
> > > automatic downcast during function calls.
> > > let's have:
> > > struct Base{};
> > > struct Der : Base{};
> > >
> > > void g(Base* b);
> > > void g(Der* d);
> > >
> > > void f(upcasted Base* b) // see below
> > > {
> > > g(b);
> > > }
> > >
> > > void main(void)
> > > {
> > > Der d;
> > > f(&d);
> > > }
> > >
> > > - The idea here is that f ignores the function that will be finally
> > > invoked, but knows that the pointer was upcasted ('upcasted'
> > > keyword).
> > > Then, the function accepting the most derived class (closest to the
> > > original type) will be invoked, in this case: g(Der*).
> > >
> > > The 'spirit' of this is to recover specificity: in the process flow:
> > > main -> f -> g
> > > specificity(main) = specificity(g) > specificity(f)
> > > and this would be an automatic way of recoviring specificity at g,
> > > without loosing generality at f.
> > >
> > > What you think?
> Daniel.Miller@tellabs.com ("Dan'l Miller") wrote
something about global flow analysis, which misses the point.
> I'm talking ... a kind of condition using RTTI.
...
> can be achieved using a reduced set of RTTI primitives. I think, that
...
> just with some additional entry in the v-table.
Basically you want to do with free functions, the same thing that is
done with virtual functions. I think another thing that would accomplish
what you want is to move virtual functions out of the class definition:
struct Base {};
struct Der : public Base {};
virtual void g(Base*) { std::cout << "g(Base*)"; }
virtual void g(Der*) { std::cout << "g(Der *)"; }
void callg(Base*b) { g(b); }
int main() {
Base b; callg(&b); // Displays "g(Base*)"
Der d; callg(&d); // Displays "g(Der *)"
}
Consider refactoring your code. If possible, put a member function in
Base and Der that simply call g() as appropriate. Works today, without
any changes to the language.
struct Base {
virtual void callg() { g(this); }
};
struct Der : public Base {
virtual void callg() { g(this); }
};
virtual void g(Base*) { std::cout << "g(Base*)"; }
virtual void g(Der*) { std::cout << "g(Der *)"; }
void callg(Base*b) { b->callg(); }
int main() {
Base b; callg(&b); // Displays "g(Base*)"
Der d; callg(&d); // Displays "g(Der *)"
}
You might also want to examine the Visitor pattern for a more
general-purpose solution to this same problem.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: abarbati@iaanus.com (Alberto Barbati)
Date: Fri, 3 Jan 2003 07:02:03 +0000 (UTC) Raw View
danielgutson@hotmail.com wrote:
> 1) [To Kalle]: Yes, I'm talking about the second: a kind of condition
> using RTTI. The advantage -and I'm not the best for asserting this as
> far as I'm not in quality of implementations- is that -I think- this
> can be achieved using a reduced set of RTTI primitives. I think, that
> in fact RTTI is no needed (as a whole), despite any run time
> information is needed in some kind. I think that this can be achieved
> just with some additional entry in the v-table.
> What if a null pointer is passed: the null pointer contains no
> information, what means that it wasn't upcasted, it's just an
> 'original null pointer to base', then the g(Base*) should be called
> (btw, your 'else' works).
Whatever the syntax, the main problem is to select one specific
overloaded function among a set of function with the same name *at
runtime*. But RTTI (as it is now) holds information about classes, not
about functions. You need a completely new set of RTTI information, not
a reduced version of current one. Moreover, as Philippe points out, this
set might not be available when dynamic linking is used.
By the way, how would you handle situations with more than one
parameter? I mean:
void g(Base* b1, Base* b2);
void g(Base* b, Der* d);
void g(Der* d, Base* b);
void f(upcasted Base* b1, upcasted Base* b2)
{
g(b1, b2); // which g?
}
Remember that the decision must be taken at runtime, so the compiler
can't give you an error message.
Alberto
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 3 Jan 2003 16:43:30 +0000 (UTC) Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) wrote (abridged):
> - The idea here is that f ignores the function that will be finally
> invoked, but knows that the pointer was upcasted ('upcasted'
> keyword).
> Then, the function accepting the most derived class (closest to the
> original type) will be invoked, in this case: g(Der*).
>
> The 'spirit' of this is to recover specificity: in the process flow:
> main -> f -> g
> specificity(main) = specificity(g) > specificity(f)
> and this would be an automatic way of recoviring specificity at g,
> without loosing generality at f.
To me this looks like a form of multi-method. As traditionally formulated,
multi-methods change the syntax for the callee, rather than the caller as
you have it. Your example would be written:
struct Base{};
struct Der : Base{};
void g(virtual Base* b);
void g(virtual Der* d);
void f(Base* b)
{
g(b); // May invoke the Der-specific version.
}
See Stroustrup's "Design and Evolution of C++" $13.8 for more details.
> What you think?
The basic aim - to recover specificity - is good. Stroustrup wanted it
too, and says he regretted not being able to include multi-methods in C++.
He describes the issues in D&E. It's welcome to see a fresh approach.
One problem with changing the caller is that you might have several calls
in scope and not want them all to use the dynamic dispatch. Eg:
void f2( upcasted Base *b ) {
g(b); // Want dynamic dispatch here.
h(b); // Don't want it here.
}
We might want to turn it off because, when multiple arguments are
involved, the call may be ambiguous at run-time. (And there may be
performance reasons, too.)
Another problem is that calls to the same function may be resolved
dynamically in some places and statically in others, by accident, if
someone forgets to say "upcasted" at the point of call.
Other issues, common to ordinary multi-methods, are (a) how to handle
ambiguous cases with multiple arguments (can errors be detected at
compile-time?); and (b) how to implement it efficiently.
And there are some details which are not clear. Are you supposing that the
only candidate functions are the ones in scope at the point of call? This
would make the mechanism less flexible. In effect, f() needs to know about
every derived class of Base, which kinda goes against object oriented
principles.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: abarbati@iaanus.com (Alberto Barbati)
Date: Thu, 2 Jan 2003 19:17:00 +0000 (UTC) Raw View
danielgutson@hotmail.com wrote:
> What you think?
What's the point in defining f taking a Base* if I mean Derived*? (or at
least I mean Derived* for overloading resolution). In other words: why
should I choose this syntax instead of declaring f taking a Derived*?
What about Base having more than one derived class? For example if
struct Base{};
struct Der1 : Base{};
struct Der2 : Base{};
void g(Base* b);
void g(Der1* d);
void g(Der2* d);
void f(upcasted Base* b)
{
g(b); // which g?
}
What if one or more derived classes are incomplete at the point of
declaration of f? For example:
struct Base{};
struct Der;
void g(Base* b);
void g(Der* d);
void f(upcasted Base* b)
{
g(b); // which g?
}
struct Der : Base{};
If I have to give one frank opinion, I would say that this syntax is
both useless, error-prone and difficult for a compiler to implement
correctly. Maybe I'm not understanding it correctly...
Alberto
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Thu, 2 Jan 2003 19:23:07 +0000 (UTC) Raw View
> automatic downcast during function calls.
> let's have:
> struct Base{};
> struct Der : Base{};
>
> void g(Base* b);
> void g(Der* d);
>
> void f(upcasted Base* b) // see below
> {
> g(b);
> }
>
> [...]
>
> Daniel.
>
In practice, I think that the compiler would have to knows every derived
classes to make it works and this is not really feasible particulary if some
module are dynamically linked.
The solution to your problem is either to add a virtual function to you base
class and call it (you may also uses design pattern like the "Visitor"):
struct Base { virtual void do_g(); };
struct Derived : Base { virtual void do_g(); };
void f(Base *b) {
b->do_g();
}
>From that, some imagination and possibly also with generic (template) code
(see Kalle post), you would be able to do what you want... If you do not
want to mess up the base class with a lot of stuff, you may prefer to have
one "creator" function that will create another object (derived from another
base class) on which you would call those functions...
One problem with template (only) based solution it that they will work on
static type. For example, it won't apply to a container of polymorphic
pointers.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: danielgutson@hotmail.com (danielgutson@hotmail.com)
Date: Thu, 2 Jan 2003 20:24:44 +0000 (UTC) Raw View
Daniel.Miller@tellabs.com ("Dan'l Miller") wrote in message news:<3E120608.6060608@tellabs.com>...
> danielgutson@hotmail.com wrote:
> > People: I'd like to ask about the feasibility of this:
> > automatic downcast during function calls.
> > let's have:
> > struct Base{};
> > struct Der : Base{};
> >
> > void g(Base* b);
> > void g(Der* d);
> >
> > void f(upcasted Base* b) // see below
> > {
> > g(b);
> > }
> >
> > void main(void)
> > {
> > Der d;
> > f(&d);
> > }
> >
> > - The idea here is that f ignores the function that will be finally
> > invoked, but knows that the pointer was upcasted ('upcasted'
> > keyword).
> > Then, the function accepting the most derived class (closest to the
> > original type) will be invoked, in this case: g(Der*).
> >
> > The 'spirit' of this is to recover specificity: in the process flow:
> > main -> f -> g
> > specificity(main) = specificity(g) > specificity(f)
> > and this would be an automatic way of recoviring specificity at g,
> > without loosing generality at f.
> >
> > What you think?
>
> I think that this works well at compile-time only 1) if one has a single
> compilation unit or 2) if one has global analysis among separate compilation
> units. In practice "compilation unit" normally corresponds to a .c/.cpp/.cxx/.C
> file which begets a .o/.obj file.
>
> Because C's (and thus C++'s) compilation model is predicated on separate
> compilation, this proposed feature is in turn predicated on the hypothetical
> removal of separate compilation from C++/C. Such removal of the
> separate-compilation axiom appears quite unlikely to me in the foreseeable future.
>
> I think that human-authored code can be written to
> overtly/manually/nonautomatically accomplish this via RTTI at run-time.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
First of all, thanks for your answers.
Two things:
1) [To Kalle]: Yes, I'm talking about the second: a kind of condition
using RTTI. The advantage -and I'm not the best for asserting this as
far as I'm not in quality of implementations- is that -I think- this
can be achieved using a reduced set of RTTI primitives. I think, that
in fact RTTI is no needed (as a whole), despite any run time
information is needed in some kind. I think that this can be achieved
just with some additional entry in the v-table.
What if a null pointer is passed: the null pointer contains no
information, what means that it wasn't upcasted, it's just an
'original null pointer to base', then the g(Base*) should be called
(btw, your 'else' works).
2) About separated compilation units: I think that there is no need of
a whole program analysis (am I getting your point?), as far as, as I
think above, this can be achieved with an additional entry in the
vtables, and any indirection mechanism using that entry.
Do you think it is possible in this way?
Before I mess in the implementation of such mechanism, please provide
me some
feedback about the usage. What do you think about the concept I
describe?
Thanks!
Daniel.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: danielgutson@hotmail.com (danielgutson@hotmail.com)
Date: Tue, 31 Dec 2002 19:25:51 +0000 (UTC) Raw View
People: I'd like to ask about the feasibility of this:
automatic downcast during function calls.
let's have:
struct Base{};
struct Der : Base{};
void g(Base* b);
void g(Der* d);
void f(upcasted Base* b) // see below
{
g(b);
}
void main(void)
{
Der d;
f(&d);
}
- The idea here is that f ignores the function that will be finally
invoked, but knows that the pointer was upcasted ('upcasted'
keyword).
Then, the function accepting the most derived class (closest to the
original type) will be invoked, in this case: g(Der*).
The 'spirit' of this is to recover specificity: in the process flow:
main -> f -> g
specificity(main) = specificity(g) > specificity(f)
and this would be an automatic way of recoviring specificity at g,
without loosing generality at f.
What you think?
Daniel.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kon@iki.fi (Kalle Olavi Niemitalo)
Date: Thu, 2 Jan 2003 02:26:24 +0000 (UTC) Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) writes:
> void f(upcasted Base* b) // see below
> {
> g(b);
> }
In current C++, there are at least two ways to define this
function.
If you want the choice of g() to be made at compile time, based
on the static type of the argument given to f, then you can use
a template:
template <typename T>
void f(T *b)
{
/* TODO: Put something here to ensure that
T is derived from Base. */
g(b);
}
If the choice must be made at run time, based on the type of the
most derived object, then you can use RTTI:
void f(Base *b)
{
if (Der *d = dynamic_cast<Der *>(b))
g(d);
else
g(b);
}
However, RTTI requires polymorphic types; Base would then need at
least one virtual function member.
These two methods differ in the following way:
int main()
{
Der d;
Base *b = &b;
f(b);
}
With the template, this calls f<Base>(Base *) which in turn calls
g(Base *); with the RTTI check, this calls f(Base *) which in
turn calls g(Der *).
Would your "upcasted" syntax be semantically equivalent to either
of these methods?
What happens if the parameter is a null pointer?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Daniel.Miller@tellabs.com ("Dan'l Miller")
Date: Thu, 2 Jan 2003 06:39:24 +0000 (UTC) Raw View
danielgutson@hotmail.com wrote:
> People: I'd like to ask about the feasibility of this:
> automatic downcast during function calls.
> let's have:
> struct Base{};
> struct Der : Base{};
>
> void g(Base* b);
> void g(Der* d);
>
> void f(upcasted Base* b) // see below
> {
> g(b);
> }
>
> void main(void)
> {
> Der d;
> f(&d);
> }
>
> - The idea here is that f ignores the function that will be finally
> invoked, but knows that the pointer was upcasted ('upcasted'
> keyword).
> Then, the function accepting the most derived class (closest to the
> original type) will be invoked, in this case: g(Der*).
>
> The 'spirit' of this is to recover specificity: in the process flow:
> main -> f -> g
> specificity(main) = specificity(g) > specificity(f)
> and this would be an automatic way of recoviring specificity at g,
> without loosing generality at f.
>
> What you think?
I think that this works well at compile-time only 1) if one has a single
compilation unit or 2) if one has global analysis among separate compilation
units. In practice "compilation unit" normally corresponds to a .c/.cpp/.cxx/.C
file which begets a .o/.obj file.
Because C's (and thus C++'s) compilation model is predicated on separate
compilation, this proposed feature is in turn predicated on the hypothetical
removal of separate compilation from C++/C. Such removal of the
separate-compilation axiom appears quite unlikely to me in the foreseeable future.
I think that human-authored code can be written to
overtly/manually/nonautomatically accomplish this via RTTI at run-time.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: kon@iki.fi (Kalle Olavi Niemitalo)
Date: Thu, 2 Jan 2003 06:54:20 +0000 (UTC) Raw View
kon@iki.fi (Kalle Olavi Niemitalo) writes:
> Der d;
> Base *b = &b;
Oops, of course I meant &d here.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]