How does C++ handle non-virtual function calls on a pointer? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I've searched but couldn't find any results (my terminology may be off) so forgive me if this has been asked before. I'm probably using the wrong search keywords.
I understand how vtables are used to handle virtual function calls on a pointer, specifically when "use after free" vulnerabilities come into play.
However, suppose you have a pointer to myclass and you call function myfunction on it when myfunction is NOT implemented virtually?
According to a bit of reading, there is one less fetch, IE instead of fetching the address of the function, then fetching the function, then calling, it is fetched directly.
Howver what confuses me is how this would work if the pointer to myclass had been freed before use.
EDIT: previous paragraph unclear, I am trying to figure out what sort of undefined behaviour might be expected.
Can anyone clear this up for me? If my question is unclear I will clarify...
CodeLion
EDIT:
MyClass *myclass;
free(myclass);
myclass->DoSomething();
Declaration of DoSomething()
void DoSomething{...} // NOT virtual void DoSomething

The short answer is undefined behaviour.
The long answer is based off a typical C++ implementation.
For a non-virtual method, the method is basically a function with an extra parameter that is automatically passed called this: often an atypical calling convention is also used, but that does not matter much.
So foo->method() becomes Foo::method(foo) in effect, and passing a bad (freed) foo is just like passing any other bad/freed parameter.
Relying on this is a bad idea, as the compiler is free to mess with you if you use an invalid this to invoke a non-virtual method.

This is because the address of the function is known at compile time because it can't possible be anything else. Whereas with a virtual function it needs to use the vtable to determine what function to call at runtime.
If the memory where your pointer to the object the method is being called on was already freed then it would just be undefined behavior the same as if it was a virtual function call because the pointer doesn't point to an instance of My class.

Let me make a different interpretation of the OP's question.
If DoSomething is a virtual function, then
myclass->DoSomething () ; // Should be my object
requires the compiler to generate code that examines the object reference by my class and determine what DoSomething to call at run time. If myclass has been deleted
delete myclass ;
then the behavior during this lookup is undefined and the translation process itself provides a point of failure.
If DoSomething is a non virtual function then, this does not require the compiler to implement a procedure to determine which DoSomething to call at run time. The compile might use the exact same process is uses with a virtual function but this would not strictly be necessary. Assuming that the compiler does not generate code for a run time lookup, doing something like
CALL MyClass_DoSomething
then this would not provide a point of failure for an undefined object referenced by myclass. However, the method needs to know which object called it. The compiler is likely to do this as an argument, doing something like for your code:
MOV EAX, myclass
CALL MyClass_DoSomething
or
PUSH myclass
CALL MyClass_DoSomething
This reference to the object has undefined, indeterminate behavior.

Related

Code runs without pointer being initialized [duplicate]

This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 1 year ago.
I was given the following as an interview question:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
What will happen when this code is executed, and why?
See also:
When does invoking a member function on a null instance result in undefined behavior?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun" since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
By the standard, this is undefined behavior and therefore a very bad thing. In reality of most programming platforms (across both X86 and several other architectures) this will run fine.
Why? Consider how class functions are implemented in C++. This isn't a virtual function, therefor this can be a static call to a known address.
In x86 assembly, we can see this as
mov A, 0
mov ecx, A
call a__fun
since a__fun requires no instance data, even though it receives a null this pointer, nothing will happen.
Still shitty code and any compiler will scream, but it can run.
The most likely behavior, on most modern computers, is that it will run, and print "fun", because:
C++ doesn't check whether the pointer is NULL before calling the function
fun() is not virtual, so there's no need to refer to a vtable to call fun()
fun() never access any member variables in A so it doesn't need to dereference
the null this pointer.
We can't know what will. Everything can happen, because the program exposes undefined behavior. See Does invoking a member function on a null instance cause undefined behavior?.
I have tried multiple times,all the time output is coming "fun" this is because function fun is independent of instance a. while calling a->fun(); a points to 0 so this is undefined behavior but in most of the compilers there should be no crash.
Three points might help:
1) All Functions are stored in code or text section.
2) Non Virtual functions are resolved at complie time.
3) While calling to member functions of class, we pass current object as this pointer to that function.
Coming to your question , here fun() function is already in memory(code section / text section).
As function fun() is non virtual , it will be resolved at complie time (i.e, for this line it will jump to instruction X at code section with this pointer as NULL).
As no member variable and no virtual function are used/called in fun() function, it is working fine.

Method is still working after moving smart pointer ownership [duplicate]

This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 1 year ago.
I was given the following as an interview question:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
What will happen when this code is executed, and why?
See also:
When does invoking a member function on a null instance result in undefined behavior?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun" since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
By the standard, this is undefined behavior and therefore a very bad thing. In reality of most programming platforms (across both X86 and several other architectures) this will run fine.
Why? Consider how class functions are implemented in C++. This isn't a virtual function, therefor this can be a static call to a known address.
In x86 assembly, we can see this as
mov A, 0
mov ecx, A
call a__fun
since a__fun requires no instance data, even though it receives a null this pointer, nothing will happen.
Still shitty code and any compiler will scream, but it can run.
The most likely behavior, on most modern computers, is that it will run, and print "fun", because:
C++ doesn't check whether the pointer is NULL before calling the function
fun() is not virtual, so there's no need to refer to a vtable to call fun()
fun() never access any member variables in A so it doesn't need to dereference
the null this pointer.
We can't know what will. Everything can happen, because the program exposes undefined behavior. See Does invoking a member function on a null instance cause undefined behavior?.
I have tried multiple times,all the time output is coming "fun" this is because function fun is independent of instance a. while calling a->fun(); a points to 0 so this is undefined behavior but in most of the compilers there should be no crash.
Three points might help:
1) All Functions are stored in code or text section.
2) Non Virtual functions are resolved at complie time.
3) While calling to member functions of class, we pass current object as this pointer to that function.
Coming to your question , here fun() function is already in memory(code section / text section).
As function fun() is non virtual , it will be resolved at complie time (i.e, for this line it will jump to instruction X at code section with this pointer as NULL).
As no member variable and no virtual function are used/called in fun() function, it is working fine.

throwing exception but still able to call member function [duplicate]

This question already has answers here:
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 1 year ago.
I was given the following as an interview question:
class A
{
public:
void fun()
{
std::cout << "fun" << std::endl;
}
};
A* a = NULL;
a->fun();
What will happen when this code is executed, and why?
See also:
When does invoking a member function on a null instance result in undefined behavior?
It's undefined behavior, so anything might happen.
A possible result would be that it just prints "fun" since the method doesn't access any member variables of the object it is called on (the memory where the object supposedly lives doesn't need to be accessed, so access violations don't necessarily occur).
By the standard, this is undefined behavior and therefore a very bad thing. In reality of most programming platforms (across both X86 and several other architectures) this will run fine.
Why? Consider how class functions are implemented in C++. This isn't a virtual function, therefor this can be a static call to a known address.
In x86 assembly, we can see this as
mov A, 0
mov ecx, A
call a__fun
since a__fun requires no instance data, even though it receives a null this pointer, nothing will happen.
Still shitty code and any compiler will scream, but it can run.
The most likely behavior, on most modern computers, is that it will run, and print "fun", because:
C++ doesn't check whether the pointer is NULL before calling the function
fun() is not virtual, so there's no need to refer to a vtable to call fun()
fun() never access any member variables in A so it doesn't need to dereference
the null this pointer.
We can't know what will. Everything can happen, because the program exposes undefined behavior. See Does invoking a member function on a null instance cause undefined behavior?.
I have tried multiple times,all the time output is coming "fun" this is because function fun is independent of instance a. while calling a->fun(); a points to 0 so this is undefined behavior but in most of the compilers there should be no crash.
Three points might help:
1) All Functions are stored in code or text section.
2) Non Virtual functions are resolved at complie time.
3) While calling to member functions of class, we pass current object as this pointer to that function.
Coming to your question , here fun() function is already in memory(code section / text section).
As function fun() is non virtual , it will be resolved at complie time (i.e, for this line it will jump to instruction X at code section with this pointer as NULL).
As no member variable and no virtual function are used/called in fun() function, it is working fine.

can I invoke non-static method on null object in QT [duplicate]

This question already has answers here:
What will happen when I call a member function on a NULL object pointer? [duplicate]
(6 answers)
Closed 8 years ago.
How does it work?
QDesktopWidget *Desktop=NULL;
auto Desktop_Rect=Desktop->screenGeometry();
pDebug()<<Desktop_Rect.width()<<","<<Desktop_Rect.height(); //1440,900
If I rewrite it as following:
auto Desktop_Rect=QDesktopWidget::screenGeometry();//Error:screenGeometry is not a static method.
pDebug()<<Desktop_Rect.width()<<","<<Desktop_Rect.height();
Basically your question has less to do with Qt but with C++.
The pointer isn't required to call the method, but the type of the pointer.
The method might not use this, so it runs the code just fine.
The bahaviour should be undefined, depends on the implementation of screenGeometry method.
P.S. Compile with warnings AND DON'T IGNORE THEM (suggested by Jeoren in comments)
This works in all cases where you call a class method on a NULL-pointer. The compiler does not (cannot) check for valid values of the pointer at compile time. It only looks at the type of the pointer, and as long as that checks out (in this case, the QDesktopWidget class does indeed have a function called screengGeometry that accepts 0 parameters) it will happily compile your code.
However, at runtime, this will most likely crash as soon as the code in that function accesses the class's data members. That is when it tries to dereference the "this" pointer, which in this case is NULL. The fact that your first example runs successfully simply means it does not access instance data, but only static or global data.
The second snippet is simply a completely different case, where you are trying to call a method as if it was static, while it is not. This results in the entirely correct and helpful error message you quote.
Ask yourself this though: What should the function return when you call screenGeometry when there is no instance to which it belongs. Both code snippets try to do something nonsensical.

Member function pointer to integer?

Is it possible to get the virtual address as an integer of a member function pointer?
I have tried.
void (AClass::*Test)();
Test = &AClass::TestFunc;
int num = *(int*)&Test;
But all that does is get me the virtual address of a jmp to the function. I need the actual functions virtual address.
I know this is old, but since there's no meaningful on-the-subject answer, here I go.
Some things need to be taken into account first.
Member-function calling convention in C++ is called __thiscall. This convention is almost identical to __stdcall, the only significant difference being that, before the effective call is made, ECX is set to be the pointer this of the object of which's method is called.
To illustrate this and answer your question at the same time, let's say that the class AClass has a member function declared like this: int AClass::myFunction(int a, int b) and that we have an instance of AClass called aClassObject.
Here's a rather hackish way to do what you initially asked for AND 'simulate' a AClass::myFunction call on the aClassObject once you obtain the raw pointer:
// declare a delegate, __stdcall convention, as stated above
typedef int (__stdcall *myFunctionDelegate)(int a, int b);
// here's the 'hackish' solution to your question
char myFunctionPtrString[10];
sprintf(myFunctionPtrString, "%d", &AClass::myFunction);
int myFunctionPtr = atoi(myFunctionPtrString);
// now let's call the method using our pointer and the aClassObject instance
myFunctionDelegate myFunction = (myFunctionDelegate)myFunctionPtr;
// before we make the call, we must put a pointer to aClassObject
// in ECX, to finally meet the __thiscall calling convention
int aClassObjectPtr = (int)&aClassObject;
__asm{
mov ecx, aClassObjectPtr
}
// make the call!
myFunction(2, 3);
And of course, the instance can be any instance of type AClass.
No, member function pointers can have a variety of sizes (from 4-16 bytes or more depending on platform, see the table in the article) and cannot reliably fit inside the space of an integer. This is because virtual functions and inheritence can cause the compiler to store several pieces of information in order to call the correct function, so in some cases there is not a simple address.
While I can't say definitively whether there is a portable way to do this, I generally recommend making a static wrapper function to provide this type of external access to a class method. Otherwise even if you succeeded you would be creating very tight coupling of the application to that class implementation.
If this is what I suspect it is, just switch off incremental linking. In the mean time, you're getting the right answer.
My other suspicion is that TestFunc may be virtual. For virtual functions whose address is taken, VC++ fakes up a little thunk that does the vtable lookup, and gives a pointer to that thunk as the address. (This ensures the correct derived function is found when the actual object is of a more-derived type. There are other ways of doing this, but this allows such pointers to be a single pointer and simplifies the calling code, at the cost of double jump when they're called through.) Switch on assembly language output for your program, and look through the result; it should be clear enough what's going on.
Here, too, what you're getting is the correct answer, and there's no way to find out the address of the "actual" function. Indeed, a virtual function doesn't name one single actual function, it names whichever derived function is appropriate for the object in question. (If you don't like this behaviour, make the function non-virtual.)
If you REALLY need the genuine address of the actual function, you've got two options. The annoying one is to write some code to scan the thunk to find out the vtable index of the function. Then look in the vtable of the object in question to get the function.
(But note that taking the address of a non-virtual function will give you the address of the actual function to call, and not a thunk -- so you'd have to cater for this possibility as well. The types of pointers to virtual functions and pointers to non-virtual functions are the same.)
The easier one is to make a non-virtual function that contains the code for each virtual function, then have each virtual function call the non-virtual function. That gives you the same behaviour as before. And if you want to find out where the code is, take the address of the non-virtual function.
(In either case, this would be difficult to make work well, it would be annoying, and it would be rather VC++-specific -- but you could probably make it happen if you're willing to put in the effort.)