I have one clarification
What is the difference between calling a function through function pointer and calling a function directly by name ?
Anybody help me in this.
There is no difference in the actual call. Parameters are passed the same way, the function runs the same way, and the return value comes back the same way.
The only difference is that you can make the function pointer point somewhere else.
There is no difference except that a compiler/linker calculates exactly what address to transfer control of the program to when you call a function by name and hardcodes that value into the code, whereas with function pointers, the computer must use the pointer to calculate where to transfer control to at runtime.
No difference (except that calling by name will always call the same function, and pointer can be changed to point to different functions).
While the direct use of function pointers does not have any cost, you should bear in mind that function pointers aren't compile time constants, so it maybe has a cost to read them. So if you have a function pointer inside a class and use that to emulate polymorphic behavior, you won't get any speedup at all.
Related
Edit How is this in any way related to the supposed post? They are both completely different errors, you guys should really stop trying to farm rep
So I've been searching around google and stackoverflow but I couldn't find one solution that would help my case.
I have a D3D9Device pointer and I want the EndScene address of that device, how would I approach so?
DWORD aEndScene = *(DWORD*)(&d3ddev->EndScene);
won't work with the following error
'&': illegal operation on bound member function expression
I think that's wrong because I'm actually trying to get the address of the d3ddev class
Member function pointers are not per object, they are per type. In your example, you could have multiple instances of a IDirect3DDevice9, all of which would have the same pointer value for their EndScene member function (assuming they aren't different concrete types - but this isn't likely).
The specific error you are getting is because you are attempting to get the address of a pointer-to-member function from an object, which isn't valid (eg. see '&' illegal operation on bound member function expression error).
It is possible to get the value of a member function using the type, instead of an object pointer. However, it's extremely ugly:
// Value is stored in 'end_scene':
HRESULT (IDirect3DDevice9::* end_scene)() = &IDirect3DDevice9::EndScene;
// Call the function, with the value of 'end_scene'.
(*d3ddev.*(end_scene))();
// Print the address of the pointer-to-member function:
printf("%p\n", end_scene);
I wouldn't suggest doing this here, because most functions in IDirect3DDevice9 don't have the same prototype. In fact, only BeginScene has the same prototype as EndScene, and it's hard to imagine a situation in which the call could be one or the other, since they need to be called in a specific order. You could make the case about using this for the functions that get/set vertex/pixel shader constants, as they have the same prototypes, but, it's just as easy to store some other external state to determine which function to call, and much more straightforward.
This is something that recently crossed my mind, quoting from wikipedia: "To initialize a function pointer, you must give it the address of a function in your program."
So, I can't make it point to an arbitrary memory address but what if i overwrite the memory at the address of the function with a piece of data the same size as before and than invoke it via pointer ? If such data corresponds to an actual function and the two functions have matching signatures the latter should be invoked instead of the first.
Is it theoretically possible ?
I apologize if this is impossible due to some very obvious reason that i should be aware of.
If you're writing something like a JIT, which generates native code on the fly, then yes you could do all of those things.
However, in order to generate native code you obviously need to know some implementation details of the system you're on, including how its function pointers work and what special measures need to be taken for executable code. For one example, on some systems after modifying memory containing code you need to flush the instruction cache before you can safely execute the new code. You can't do any of this portably using standard C or C++.
You might find when you come to overwrite the function, that you can only do it for functions that your program generated at runtime. Functions that are part of the running executable are liable to be marked write-protected by the OS.
The issue you may run into is the Data Execution Prevention. It tries to keep you from executing data as code or allowing code to be written to like data. You can turn it off on Windows. Some compilers/oses may also place code into const-like sections of memory that the OS/hardware protect. The standard says nothing about what should or should not work when you write an array of bytes to a memory location and then call a function that includes jmping to that location. It's all dependent on your hardware and your OS.
While the standard does not provide any guarantees as of what would happen if you make a function pointer that does not refer to a function, in real life and in your particular implementation and knowing the platform you may be able to do that with raw data.
I have seen example programs that created a char array with the appropriate binary code and have it execute by doing careful casting of pointers. So in practice, and in a non-portable way you can achieve that behavior.
It is possible, with caveats given in other answers. You definitely do not want to overwrite memory at some existing function's address with custom code, though. Not only is typically executable memory not writeable, but you have no guarantees as to how the compiler might have used that code. For all you know, the code may be shared by many functions that you think you're not modifying.
So, what you need to do is:
Allocate one or more memory pages from the system.
Write your custom machine code into them.
Mark the pages as non-writable and executable.
Run the code, and there's two ways of doing it:
Cast the address of the pages you got in #1 to a function pointer, and call the pointer.
Execute the code in another thread. You're passing the pointer to code directly to a system API or framework function that starts the thread.
Your question is confusingly worded.
You can reassign function pointers and you can assign them to null. Same with member pointers. Unless you declare them const, you can reassign them and yes the new function will be called instead. You can also assign them to null. The signatures must match exactly. Use std::function instead.
You cannot "overwrite the memory at the address of a function". You probably can indeed do it some way, but just do not. You're writing into your program code and are likely to screw it up badly.
Let say I have a array which is very big verybigvariable
And I have defined a function that does some operations like this
function myfunc(var) result(res)
real:: var(:,:,:),res
...
...
...
end function myfunc
My question is that when I call this function like this
myvar=myfunc(verybigvariable)
what happens? does it duplicate my variable so it holds 2X space in the ram during the execution of the function? If so how can I prevent this? (In a simple program, I know, I can define the function without any parameter and make it use existing variables, but If I am programming a module, it seems I have to include parameter to the definition)
The Fortran language standard does not specify how arguments are passed. Typically in the interest of efficiency the compiler will not make a copy but pass the address of the argument. There will be cases in which a Fortran compiler has to make a copy. E.g., the actual argument is a non-contiguous array but the procedure expects a contiguous argument. The compiler will have to fix the mismatch by making a copy that is contiguous to pass to the procedure. If the procedure modifies that argument, the values have to be copied back to the original argument.
In fortran it seems that parameters are passed by reference. This means that only the address of the variable is passed, and the function can then access the variable through that address.
So no, the array is not copied, only the address of the array is passed. The overhead for this will be either 32 bits for a 32-bit system, or 64 bits for a 64-bit system.
I have no experience with fortran, and this is only what I could figure out though a Google search, so if any Fortran programmers have any remarks, please feel free to edit/comment.
What's the real benefit of using pointers to functions instead of those functions itself? Does it make execution faster ? Or does it provide convenience when it's passed to another function?
It enables you to "select" a component of your business logic around at run time -- contrast this with hardcoding the function names, which limits you to choosing which function to use at compile time.
There are situations where you must use a pointer to function, there is no other way. For example, to implement a callback function, specifying comparator function(the last parameter in sorting routines).
EDIT: As specified in the comment, this is about C. Function pointer came from C.
Function pointers are how you store functions in variables and pass them into other functions. There are no "advantages" over "regular functions", they are completely different things and trying to compare them doesn't make sense. It's like asking "which is better, variables or if statements?"
Function pointers provide a functionality that would otherwise be unavailable.
In fact passing a pointer of a function is a little bit slower than calling the function itself. But the difference is so little that it can hardly ever have any effect.
As Jon said, it brings more flexibility in some cases, when you can pass the function from one part of your programm to another.
function pointers are used in many situations where you are not sure which function to call exactly. Lets take an example. you want to sort an array. For that you want to write a generic sort function . Now this sorting function needs to compare the array elements. But since array can have any elements (int, floats, strings, user defined types etc), how this sort function can compare the elements. So, in this case, you can pass the ordering-determining function as an argument to this sort function and based on that it can sort the array. Also, it is usefull in another way as well. Lets say you want to sort an array of string (a string of numbers). you may want to sort it numerrically or in alphabatically.
In this case, when you want to sort nnumerically, you can pass compare function which compares based on the value of string converted to int. and so on...
I've got a function that takes a list of CRuntimeClass pointers in order to setup a view. I'd like to return without doing anything if the function is called with a list of the same classes that are already setup. Saving the pointer values and comparing them on the next call is currently working, but I want to verify that that's a legal thing to do, and not something that just happens to work. Maybe my doc-search-fu is lacking, but I can't find anywhere that guarantees the pointer value returned from the RUNTIME_CLASS() macro for a given class will be the same for the life of the program. The closest I could find is in the docs for CObject::GetRuntimeClass():
There is one CRuntimeClass structure for each CObject-derived class.
That implies that the pointer value shouldn't change, but doesn't exactly state it. Does anyone have something a bit more concrete on that? Or is there a better way to compare the CRuntimeClasses?
No such guarantee is documented, albeit that it is likely. You are supposed to use CObject::IsKindOf().
Taking a peek at afx.h plus a little of debugging shows that RUNTIME_CLASS() returns a pointer to a static member: static CRuntimeClass class##class_name (as it can be seen in the definition of DECLARE_DYNAMIC(class_name) macro).
As the member is static, the pointer to it does not change during runtime. In other words static is your guarantee.