[Ns-developers] A question about downcast netdevice pointer.

craigdo@ee.washington.edu craigdo at ee.washington.edu
Thu Sep 25 16:36:21 PDT 2008


> [moving this to ns-developers to avoid bringing pointless low-level
> details on ns-3-users. Please, in the future, avoid dumping all this
> complexity/argumenting on ns-3-users: it serves absolutely no 
> purpose.]

This is not true.  The purpose it serves is to help a user who was confused
about how there could be two Objects accessible via GetObject in a single
C++ object understand what was going on since there was no explicit
aggregation.  The same thing applies in other places as I have said.  There
was no argument, just explanation and context.  

You could say that a manual is dumping pointless low-level details on
ns-3-users.  I disagree.  If someone is attempting to do things at this
level, they need a description of what is going on at this level.

I don't know where you get the argument part of my email.  But at this
point, it's looking more like an argument :-(

> > is and how it works.  Also we need to document that, for example,
> > CsmaNetDevice presents itself to the world as an 
> aggregation of Object,
> > NetDevice and CsmaNetDevice and one can maneuver around these using
> 
> This is not true. Aggregation has nothing to do here.

No, this is true.  This is tied into aggregation since Objects can be
aggregated, CsmaNetDevice has a TypeId and is an Object, and NetDevice has a
TypeId and is an Object.  If you want to aggregate another Object to a
CsmaNetDevice, you can.  Then you could use GetObject to discover that
Object and you could use GetObject to discover the NetDevice from
CsmaNetDevice and vice versa.  This is true because in the case of an
aggregation with an Object implemented via inheritance, all interfaces are
accessible via the same mechanism -- GetObject.  You may think it's an
accident -- I think it's fairly elegant.

The only missing piece is explaining how it works in a consistent manner,
which has dropped out of our documentation package.  I have said this
several times today.  See the Ipv4Impl case below.

> GetObject to do a
> downcast is just convenient syntactical sugar and I support gustavo's
> proposal to use a DynamicCast template to avoid using it in this case
> and disambiguate the usage. 

Having GetObject do a downcast for you allows you to treat the CsmaNetDevice
/ NetDevice Object as two aggregated Objects with two interfaces even though
they are not explicitly constructed that way.  It allows you to get to
different Objects without having to understand that they are implemented in
a certain specific way.  It's really quite simple:  a user only has to
remember one way to get one Object pointer from another and doesn't have to
care about how the underlying Object was made.

We decided long ago that how one looks at this is a matter of personal
taste.  I thought I explained this in some detail in my email.  I support
Gustavo's template for those who are more comfortable looking at certain
instances of Objects that are built by inheritance were a dynamic cast
operation makes sense to them.  I support using GetObject as a generic
interface discovery mechanism for aggregated Objects a la COM.  I support
using GetObject as a way to perform casts since, conceptually, the cast
operation is just another way to "discover" an interface.  I support giving
people enough knowledge to intelligently choose between the different ways.

What I don't do is insist you look at each problem in one sanctified way.

> We don't have COM: we have normal C++ class single inheritance with a
> very simple dynamic object aggregation facility which has 
> nothing to do
> with COM. 

Umm, sure.  I said that quite clearly and explicitly several times:  "We
decided that pure virtual Interfaces in the COM sense aren't what we deal
with -- we are talking about Objects which are really C++ objects" and "we
decided it was important to convey that we were getting a pointer to an
underlying C++ object, not some other special kind of thing."

> Claiming that we attempt to provide "implementation hiding"
> through GetObject is just meaningless. We are not in that business
> (implementation hiding) beyond trying to design good, nice, and clean
> abstract base classes and that has nothing to do with object
> aggregation.

Where did I say this?  I don't have any idea where you got this.

What I said was that by using GetObject instead of dynamic_cast, you don't
have to use different operations to move between objects that were
aggregated together explicitly, versus objects that were associated together
by a different implementation (inheritance). What I said was that at the
user level, you didn't have to do access Objects differently based on
implementation details.  I didn't say anything at all about implementation
hiding in the (quite complicated and different) COM sense.

A long time ago, I went through an exercise where I showed four or five ways
we could use the existing system to implement, extend and substitute
objects.  The way the CsmaNetDevice is put together is one of those ways.
The only time you could use dynamic_cast to go betwen NetDevice and
CsmaNetDevice is if you used this one specific mechanism.  If you use
GetObject as your basic client mode of operation, you don't have to worry
about which of the N ways someone has used to implement their model.  It
works in all of the cases.  It makes sense to me and therefore I use
GetObject to do the casts.  I think it's nice.

Look, I explained why GetObject works the way it does and why it makes sense
for some people to do a GetObject instead of a dynamic_cast, as Tom
suggested.  It needs to be explained because there are other cases in the
system where you are expected to GetObject to find a C++ base class that is
hidden down in an implementation hierarchy in exactly the sense that the
NetDevice and CsmaNetDevice work together.  I refer you to class Ipv4Impl
that implements Ipv4.  This is another one of my four or five ways to build
ns-3 objects.  You absolutely do find GetObject<Ipv4> around the system.  If
you went looking for the place where Ipv4 is aggregated to a node, you
wouldn't find it.  What you would find, after lots of poking around in
source code, is that Ipv4Impl is aggregated and you get the Ipv4 for free in
exactly the same way as you get a NetDevice Object for free when you create
a CsmaNetDevice.

As I said in my email, "... in the Seattle meeting, we decided this is a
matter of style and there would not be a prescription; we decided we would
solve this issue by documentation."

I pointed out that the documentation is lacking and provided some context
for the whole GetObject approach.  GetObject makes almost no sense without
that context, whether or not you like the acronym COM.  When you provide the
context and documentation, using GetObject to cast between NetDevice and
CsmaNetDevice does make sense and the whole Ipv4Impl thing becomes
understandable because it really is all the same thing.

> If your claim is that we lack documentation about this, I agree and,
> yes, I also agree that it sucks but such is life and days 
> have a finite
> number of hours and real-life priorities often make it hard to 'do the
> right thing'.

*If* my claim is that we lack documentation?  *If* !?  Surely you jest.  The
*whole point* of my email was that we lack documentation; and to provide
something on-demand for this particular underlying question that I hoped
might make it as the beginnings of a HOWTO or WHYFOR or as impetus to revive
the Object Model section of the old manual.




More information about the Ns-developers mailing list