Archived

This topic is now archived and is closed to further replies.

Matt Calabrese

Inline Polymorphism!?

Recommended Posts

Are inline "virtual" methods exactly the same as regular virtual methods? In order to be virtual, a pointer is stored to the pointers to the methods of the class, so how would declaring a method as inline change this without losing the power of polymorphism in the process? The only difference I can think of is that when calling a polymorphed method via a pointer, it traverses as normal (as though it weren''t inline), but when calling via a refrence/object, the code is inserted as though it were inline. This "double role" is what I have assumed for a while. Is that a correct assumption, or no? I often times have polymorphed methods that in some forms of the inheritance are simple accessor methods, and so I declare those versions as inline. Is this pointless, or would what I mentioned above be the case, where the inline method acts as both an inline and a standard method depending on the case? Thanks in advance! -------------------- Matthew Calabrese Realtime 3D Orchestra: Programmer, Composer, and 3D Artist/Animator "I can see the music..."

Share this post


Link to post
Share on other sites
Pointless. There are some bizarre cases where the compiler might be able to do the right thing, and (from what I remember of prior discussion on this topic) it''s not illegal by any means, but odds are it''ll get placed out-of-line.

Share this post


Link to post
Share on other sites
Wow, even when the method is called via a refrence!? I didn''t expect that. Is there a reason why that I am missing?

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

Share this post


Link to post
Share on other sites
AFAIK, the compiler may be able to inline the call if its made from an object, because it knows its exact type. If the call is made from a pointer, the compiler cannot tell the type of the pointee - a pointer to base class can point to a derived class object. The same holds true for references - behind the scenes they''re basically just pointers anyway.

Share this post


Link to post
Share on other sites
Yes, I fully understand that through pointers the methods cannot be made inline (hence my first post). As for your relationship between pointers and refrences -- not true. You cannot have a refrence point to a derived version of the object as would have with a pointer, so you actually do know the exact object type when using a refrence to an object.

In my previous post when I said refrence I implied refrences as well as objects. In either case, I do not see why the call wouldn't be able to be made inline as the object type is without a doubt known.

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

[edited by - Matt Calabrese on March 19, 2002 6:28:19 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Matt Calabrese
You cannot have a refrence point to a derived version of the object as would have with a pointer, so you actually do know the exact object type when using a refrence to an object.
Wrong. In respect to polymorphism, refrences work exactly the same as pointers.
CDerived derived;
CBase& baseRef = derived;
Try it.

[edited by - wayfarerx on March 19, 2002 6:42:37 PM]

Share this post


Link to post
Share on other sites
Dang, beaten to it

Have my hefty example to ctrl-c, ctrl-v, compile anyway...


  
#include <iostream>
using namespace std;

class ABC
{
public:
virtual void foo() const=0;
virtual ~ABC(){}
};

class Concrete : public ABC
{
public:
virtual void foo() const
{
cout << "stuff" << endl;
}
void onlyinderived()
{
cout << "hmmm" << endl;
}
virtual ~Concrete(){}
};

void function(const ABC &interface)
{
interface.foo();
//interface.onlyinderived(); // This doesn''t work

}

int main()
{
Concrete thingy;
const ABC &baseref = thingy;
baseref.foo();
// baseref.onlyinderived(); // Neither does this


function(thingy);
}

Share this post


Link to post
Share on other sites
Wow! I stand corrected! Learn something new everyday I suppose. I dunno why I thought otherwise.

Either way -- my original question stands, concerning objects, would most compilers make the call inline/any compilers make the call inline?

EDIT: Just thought it was funny that you used the object name "thingy" which is usually what I use when testing stuff out. Is this a common nerd practice? I thought I was the only one :/

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

[edited by - Matt Calabrese on March 19, 2002 6:54:22 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Matt Calabrese
Either way -- my original question stands, concerning objects, would most compilers make the call inline/any compilers make the call inline?



As stoffel said, the call can only be inlined if you are explicitly calling that function

ie. Call the method like

BaseClass::Virtual_Method();

Otherwise, the compiler won''t inline it.

Share this post


Link to post
Share on other sites
Yes, I''d assume that would be the case; actually, I said something similar in my first post, though stoffel disagreed with me and said it was pointless to declare the method as inline.
More precisely, though, I was refering to this case:


  
class someclass
{
virtual void Poo() = 0;
};
class somederivedclass : public someclass
{
virtual /*inline*/ void Poo() {}
};

int main()
{
somederivedclass thingy;
thingy.Poo();
return 0;
}


Would the call to "Poo" be made inline? Since it is made directly from the object, there is no doubt which function to use so the traverse for polymorphism would be pointless. So would it be made inline for this case, or no? That''s all that I am asking. If I''m phrasing this poorly please tell me, I don''t see what the problem is.

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

Share this post


Link to post
Share on other sites
I tried this out last night on CodeWarrior 7.0. When I made the call on an object, like in your example, it was resolved statically. The call was made without using the vtable in debug mode, and inlined in release mode.

Other than that the vtable was always used. It was even used when I made an object, took a reference to it of the same type as the object and made a call on the reference.

Share this post


Link to post
Share on other sites
quote:
Original post by Matt Calabrese
Would the call to "Poo" be made inline?

The code in question can be entirely resolved statically. Therefore, the question of whether the function is inlined depends on the same rules that determine whether a function will be inlined when non-virtual. In your example, I would say the inlining issue is irrelevant, as the compiler should perform an empty method optimisation.

[edited by - SabreMan on March 20, 2002 7:04:34 AM]

Share this post


Link to post
Share on other sites
Sabreman, that was just an example. Just "pretend" there was stuff between the brackets.

--------------------
Matthew Calabrese
Realtime 3D Orchestra:
Programmer, Composer,
and 3D Artist/Animator
"I can see the music..."

Share this post


Link to post
Share on other sites
Actually, I did assume that''s what you meant. The sentence:

"the question of whether the function is inlined depends on the same rules that determine whether a function will be inlined when non-virtual"

covers that scenario. I added the sentence about your actual example as a side-note. I guess your selective reading filter must have kicked-in.

Share this post


Link to post
Share on other sites
quote:
Original post by Krunk
I tried this out last night on CodeWarrior 7.0. When I made the call on an object, like in your example, it was resolved statically. The call was made without using the vtable in debug mode, and inlined in release mode.

Other than that the vtable was always used. It was even used when I made an object, took a reference to it of the same type as the object and made a call on the reference.



This is intended behaviour. Virtual methods should only incur a vtable overhead penatly when used polymorphically (ie with base class pointers).

Share this post


Link to post
Share on other sites