pointer to function call vs pointer to member function call - c++

I always wondered why there is a stylistic difference between calling a pointer to function vs calling a pointer to a member function in terms of using the de-referencing operator *, i.e.
void(*fptr)()=&f; // pointer to function f()
fptr(); // call f() via pointer to function
Foo foo; // instance of Foo
void (Foo::*fptr)()=&Foo::f; // pointer to member function f()
(foo.*fptr)(); // call foo.f() via pointer to member function
In the first part, you don't use the * operator to call f() via the function pointer, but then one must use it in calling the member function via the pointer, (foo.*fptr)(). Why this difference? Why not just use (foo.fptr)() for consistency? Is there any profound reason or just this is the way C++ was designed?

I'll be quoting stuff from C++ Common Knowledge. The related chapter is titled Pointers to member functions are not pointers. There the author explains why pointers to member functions cannot be implemented as pointer to functions. I'll be using this (the fact that they're different things) as a justification for the different syntax :
When you take the address of a non-static member function, you don't get an address; you get a pointer to member function.
(...)
As with a pointer to data member, we need an object or pointer to an object in order to dereference a pointer to member function. (...) In the case of a pointer to member function, we need the object's address to use as (or to calculate) the value of the this pointer for the function call and possibly for other reasons as well.
Note that there is no such thing as a "virtual" pointer to member function. Virtualness is a property of the member function itself, not the pointer that refers to it.
This is one reason why a pointer to member function cannot be implemented, in general, as a simple pointer to function. The implementation of the pointer to member function must store within itself information as to whether the member function to which it refers is virtual or nonvirtual, information about where to find the appropriate virtual function table pointer, an offset to be added to or subtracted from the function's this pointer and possibly other information. A pointer to member function is commonly implemented as a small structure that contains this information, although many other implementations are also in use.
Dereferencing and calling a pointer to member function usually involves examining the stored information and conditionally executing the appropriate virtual or nonvirtual function calling sequence.
IMHO considering these differences one can justify the syntax difference, although historic design choices could have played their role.

If we simply use foo.fptr, it is the same as how we call a member function, making the compiler complex. Actually, fptr is not a member function of foo. Thus *fptr shows the difference. Maybe the compile can make that happen ,and I think that's how C++ was designed now.

Related

memory layout of C++ object

As far as my understanding all the member functions will be created in separate memory when class definition and is common for all objects. And only the member variables are created individually for each object. But how member function is executed when called using object?
Where is the address for these member function will be stored?
class B{
public:
int a;
void fun(){
}
};
int main(){
B b;
std::cout<<sizeof(b)<<std::endl;
}
If I execute this program, I get the output as 4(which is for only member variable). But calling b.fun() calls its member function correctly. How it is calling without storing its address within the object? Where the member function address are stored?
Is there anything like class memory layout where these addresses will be stored?
Non-virtual member functions are extremely like regular non-member functions, with the only difference between them being a pointer to the class instance passed as a very first argument upon invocation.
This is done automatically by compiler, so (in pseudo-code) your call b.fun() can be compiled into
B::Fun(&b);
Where B::Fun can be seen as a usual function. The address of this function does not have to stored in actual object (all objects of this class will use the same function), and thus size of the class does not include it.
Is there anything like class memory layout where these addresses will be stored?
There is for functions declared virtual, yes. In this case, the addresses of said functions are stored in a table and looked up at runtime. This in turn allows your code to dispatch to the correct function depending on the object's type when the function is called.
Non-virtual functions do not work this way. They're stored in the same way as free (i.e. non-member) functions, with the function name prefixed by the name of the class. No storage space within the object itself is required.
In both cases, a hidden this pointer is passed to the called function. This is what 'connects' it to your object.

behavior of regular function and virtual function at deletion of an object [duplicate]

This question already has answers here:
After using 'delete this' in a member function I am able to access other member functions. Why?
(2 answers)
Closed 7 years ago.
Suppose class A has a regular member function and a virtual member function, and I have two pointers pointing to the same A object. Suppose one ptr deleted the object, while the other pointer is not aware of that. What will happen if the other pointer tries to call the regular member function and the virtual member function?
I understand it is not recommended behavior of utilizing a pointer after the object is deleted, and would emphasize on the difference between regular function versus virtual function, even static member function. Exactly how does compiler treats regular function, virtual function, and even static function at compile time?
Thanks!
If you have two pointers to the same object, and you delete one, then the other is left with a dangling pointer. Trying to access anything after that is undefined behavior.
most compilers implement member functions as 'ordinary' functions with additional pointer parameter called 'this'.
So as long as you are not using anything pointed by this - such member function can work (yet such function probably shouldn't be a member).
Virtual functions are implemented differently - vtable has to be accessed via this prior to calling function (to determine which one to call).
Please remember that this difference is implementation specific - calling any method on deleted object is undefined behavior and should be avoided.

How does a pointer to virtual function differ from a pointer to a non-virtual one?

And why is it required to use "&" before function in the next piece of code?
void (Mammal::*pFunc) () const=0;
pFunc=&Mammal::Move;
Move() is a virtual function in the basic class and pFunc is a pointer to virtual function in this class.
So why we need to use "&"? According to some special properties of virtual function?
Or it is simply syntax?
An ordinary function can be called with just its address, so a pointer to an ordinary function is just an address.
A non-virtual function can also be called with just its address (plus, of course, the this pointer, passed by whatever mechanism the compiler uses), so a pointer to a non-virtual function could be just an address.
A virtual function has to be looked up by a compiler-specific mechanism (usually a vtable, at a known offset in the object; the address of the function is found by indexing into the table), and a pointer to virtual function has to contain whatever information is needed to determine what the actual function to call is, depending on the actual type of the object.
But a pointer to member function has to be able to handle both virtual and non-virtual functions, so it will have enough room for the right mechanism for both, and the runtime call will check the stored data to figure out what to do.
Some compilers provide an alternative, where if you promise that you will absolutely, positively, never store a pointer to virtual function in the pointer, the compiler will generate a smaller pointer representation, and you'll find that you're in trouble later when you break that promise.
As to why the & is required, it's required. Microsoft's early C++ compilers didn't require the & (and didn't require the class name; if you left it out you'd get a pointer to the member function of the class of the current object); they talked about proposing eliminating the rule, but it didn't get anywhere.
& is the address-of operator. While in C it is possible to simply specify the name of the function without this, in C++ you are supposed to use it with a fully qualified function name.
If I remember correctly, when you take the address of a virtual function, the compiler will actually generate an intermediate function, the address of which will then be used instead. When that intermediate function is called, all it will do is call the virtual function you specified.
In your first line, pFunc isn't a pointer to a virtual function, it's a pointer to a const method in Mammal that takes no arguments and returns void. You are then assigning 0 to that pointer.
The '&' operator is giving you the address of the Mammal::Move method in class scope, suitable for assigning to a member function pointer.
The standard requires the '&' operator, though I have used compilers that didn't require it.

The fourth parameter in pthread_create function

Code like this:
int code = pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
which QThreadPrivate::start is a static function.
So,what use is the fourth parameter this? And what is the difference if this is replaced by NULL?
This is a common idiom. You want to start a thread, but you want that thread to operate on a specific object. So you need to pass the thread a pointer to the object you want it to operate on. If you're within a member function for that object, the this pointer points to the object you're operating on. You can't pass a pointer to a member function directly (because the type would be different), so you use a static member function whose sole purpose is to cast the this pointer back to the correct type and run a non-static member function.
If you changed this to NULL, the thread would have no idea what object it was supposed to operate on. Likely, QThreadPrivate::start would fault or fail, since it would be unable to invoke a non-static member function on the instance without a pointer to that instance.
Say you have a class that has a normal member function that takes no parameters and returns no parameters. You have some code that has no idea about your class or any of its structures. You want to give that code enough information to call that member function on a particular class instance. What do you pass it? You can't pass it a pointer to the member function because with no idea about your class, it can't call a normal class member function. Answer: You pass it a pointer to a static member function whose implementation calls the normal member function, and you pass it a pointer to the instance whose method you want it to invoke.
The fourth parameter of pthread_create is passed untouched to the thread function and allows that function to change behaviour based on that argument.
OpenGroup documentation for pthread_create, detailing this, can be found here.
In this case, it's simply passing the pointer to the current object, presumably so that the start function can use that to access member variables for the specific object.
If you pass NULL instead, the created thread will get NULL and won't be able to access object specific data (without crashing and burning badly with a null pointer dereference).
You may think that, because QThreadPrivate::start is a static function, it wouldn't be able to access non-static members any way (since it generally doesn't have an object to work on).
But that only applies to implicit access - there's nothing stopping you from accessing object data through an explicit this pointer, providing you follow the access rules (e.g., no access to private data).
The fourth parameter is passed to the thread when it starts. QThreadPrivate::start can use it (after an appropriate cast) to call an object specific member function.

How does a C++ object access its member functions?

How does a C++ object know where it's member function definitions are present? I am quite confused as the Object itself does not contain the function pointers.
sizeof on the Object proves this.
So how is the object to function mapping done by the Runtime environment? where is a class's member function-pointer table maintained?
If you're calling non-virtual functions, there's no need for a function-pointer table; the compiler can resolve the function addresses at compile-time. So:
A a;
a.func();
translates to something along the lines of:
A a;
A_func(&a);
Calling a virtual function through a base-class pointer typically uses a vtable. So:
A *p_a = new B();
p_a->func();
translates to something along the lines of:
A *p_a = new B();
p_a->p_vtbl->func(p_a);
where p_vtbl is a compiler-implemented pointer to the vtable specific to the actual class of *p_a.
There are generally two ways that an object and its member functions are associated:
For a non-virtual function, the compiler determines the appropriate function at compile time. Non-static member functions are usually passed a hidden parameter that contains the this pointer, which takes care of the association of the object and the class member function.
For virtual functions, most compilers tend to use a lookup table that is usually referenced via the object's this pointer or a similar mechanism. This table, normally called the vtable, contains the function pointer for the virtual functions only.
As C++ is not a dynamic language, the compiler can do most of the object/function/symbol resolution at compile time with the exception of some virtual functions. In some cases, it's even possible for the compiler to determine exactly which instance of a virtual function gets called and skip the resolution via the vtable.
Member functions are not part of the object - they are defined statically, in one place, just like any other function. There is no magic look-up needed.
Virtual functions are different, but I don't think your question is about that...
For non-virtual functions there is one (global, per-class) function table which all instances use. Since it's the same for all of them - deterministic at compile-time - you would not want it duplicated in each instance.
For virtual functions, resolution is done at runtime and the object will contain a function table for them. Try that and look at your object again.