How can a pointer point to a function?

Asked

Viewed 124 times

1

A pointer points to a memory address, so how a pointer is able to point to a function?

If the answer is "functions also have addresses" then please give more details.

And if it is possible to answer, in C++, for example, why function pointers are different from normal?

// Ponteiro "normal"
void* p = &x;

// Ponteiro de funções
void(*p)() = f;

  • 1

    A function is stored IN ONE memory address. What changes to a variable, for example, is the form that is accessed/used. In the case of a function, in asm x86 msvc is used the instruction CALL to call her (which has a small differences of JMP). A variable can be in the address 0x00004 the function in 0x00008, will change the way they are used through specific functions of Assembly,

3 answers

6

A function is where? In memory, right? And all memory is addressable, right? So the question is why can a function be addressed? In fact a function is always addressed, even if you don’t see the pointer to it (very common for most languages to hide pointers), yet when it calls a function it is actually diverting the execution of the program to the given address according to the name of that function. The only way to access a function is by its pointer. What you are seeing there in this code is only one indirect extra created to personalize the call.

If you think a function has no address it’s because you think it’s not in the memory and if it’s not there, where is it? Or do you think there’s some part of the memory that’s not addressable, so the question would be why do you think that? Don’t make exceptions to the concept where you don’t need to.

Function pointers are no different than "normal" because they are normal, they only point to a function and if it is to use so it takes a syntax that indicates either a pointer to a function, which indicates to the compiler that that variable can be called and then it allows that call when it is made because it knows that it is not a simple given.

Pointer is the mechanism and it doesn’t change. The type of information the pointer points to changes, then the typing indicates something different and this is a case that requires an exception in the syntax.

If you want to know why you don’t use the operator & to get the function address is precisely because it is already an address (is the same question as that question), then not that do any operation to pick up the address, unlike a given you should create a pointer to be able to use if it is not yet an address.

Although it works, you don’t use this type of code in C++, you have better, more robust and more readable ways of doing this in C++, so you’re showing in the code how you do it in C, even if you do it with C++, but that’s another question.

  • A function when turning into machine code is a set of instructions, so where exactly is the address of the function?

  • The address is wherever the pointer is, which you’re using in your code or where the compiler puts it. Something tells me you want to know something specific, maybe you already know or think you do, but that’s not the question.

3

Your question is how the memory of a program is structured. Search for articles about the organization of the memory of a process for a broader view. Here I will give you only the most basic notions that will help you visualize what happens on the machine.

When you have a program run, the OS allocates a block in memory to store the information of the new process. Among this information is the program code (instructions, variables, functions etc) already linked with the libs static. It is not possible to know the exact address of where the process is and this can keep changing constantly if you have more processes running than available memory for all of them.

However, within the space allocated to the process, the instructions usually stay at the smallest addresses block. Then comes the block of static and global variables and above we have the HEAP that grows as your program allocates data dynamically. At the end of the process block (largest addresses) is the STACK that grows to smaller addresses as its functions are called.

Execute this code and watch the exit. For security reasons, the compiler does not let us manipulate/observe the address of the functions, we can only tell him that we want such a pointer to point to such a function.

As for the syntax, well... a function requires a list of parameters, an object does not. So the syntax has to be different. The parentheses around the name are for disambiguating the function declaration. The reason for not using the operator & is the same as the array. The name of a function is already a name of a pointer. However, this is optional, you can use the operator if you want.

void *pnome = &x;
void (*pnome) (<parâmetros>) = [&]f;
void *pnome(<parâmetros>) = [&]f; // ERRO: função inicializada como objeto

However, as @Maniero has already said, this syntax is inherited from C. In C++ there are better ways to work with function pointers using the std::function.

1


Yes, the function turns into a set of instructions in machine code. This function instruction set is stored in a memory address, so for example if you can use the same function many times in the program in different "places".

When declaring the function it is the same thing as declaring a variable. An address is assigned to it. And inside that address is the instructions.

In a rude way, that’s it.

  • 1

    It’s not stored in a memory address, it’s stored in memory, which has an accessible address, that’s what I wrote in my answer, not roughly.

  • When I say an "address of a place" I am referring exactly to "the place".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.