1

Having such a simple C++ function pointer example:

#include <stdio.h>

void my_int_func(int x) {
    printf("%d\n", x);
}

int main() {

    void (*foo)(int);
    foo = &my_int_func;

    foo(78);

    return 0;
}

What is the type of the address pointed by the foo? Is it just a relative address of the my_int_func function from the program starting point (the main function) and hence is it always the same (just because it is relative)?

P.S.
Sorry if the questions are obvious/lame but I'm just a beginner in the topic...

Thx for help!

Rafael
  • 7,605
  • 13
  • 31
  • 46
Daros7
  • 63
  • 5
  • have you turned off optimization? – AndersK Aug 01 '21 at 15:06
  • I believe function pointers are slightly weird in that `&` and `*` don't really do anything; `*******************my_int_func` is the same as `my_int_func`. Might be missing something though. – mediocrevegetable1 Aug 01 '21 at 15:07
  • Not sure if it's a duplicate, but related, for sure: [How does dereferencing of a function pointer happen?](https://stackoverflow.com/q/2795575/10871073) – Adrian Mole Aug 01 '21 at 15:08
  • A function decays to pointer-to-function in almost all contexts. That's why, say, `my_int_func` and `&my_int_func` are mostly the same - the latter takes the address of a function forming a pointer-to-function, the former implicitly decays to that same pointer. There are a few places where there's a difference: e.g. `sizeof(my_int_func)` doesn't compile while `sizeof(&my_int_func)` does. See also: [function to pointer conversion](https://en.cppreference.com/w/cpp/language/implicit_conversion#Function_to_pointer) – Igor Tandetnik Aug 01 '21 at 15:14
  • 1
    @mediocrevegetable1 It's not so much the weirdness of function pointer itself, but rather weirdness of function types. You cannot indirect through a function as such, but function will implicitly convert to the function pointer which you can indirect through which yields the function, which can again implicitly convert to the pointer that can be again indirected through to get the function... again and again. – eerorika Aug 01 '21 at 15:35

1 Answers1

3

Is it just a relative address of the my_int_func function from the program starting point (the main function) and hence is it always the same (just because it is relative)?

The language doesn't specify such details.

In general, addresses stored in pointers are absolute and not relative.

What they point to varies from architecture to architecture. For some architectures, function pointers point to the first instruction. For others, it points to a function descriptor. And there are architectures where additional information is encoded into the low bits of the pointer.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • @eerorikav Is it a way to tell the linker to always place the function at a specific, fixed address from the staring point? – Daros7 Aug 01 '21 at 15:27
  • @Daros7 There is no standard way. Also, you should clarify: You use "fixed address" which implies absolute and "from starting point" which implies relative. – eerorika Aug 01 '21 at 15:28
  • There are notable exceptions, such as PowerPC and Itanium, where function pointers aren't pointers to code, but rather [pointers to function descriptors](https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES). – Raymond Chen Aug 01 '21 at 15:29
  • Additionally, a function pointer is not necessarily the address of the code. In the Digital Alpha, it was the address a of a function descriptor that contained a bit mask of the registers to be saved (or something) and the address of the code. – Eric Postpischil Aug 01 '21 at 15:30
  • @eerorika By "fixed" I mean the relative address that is always fixed/the same looking from the program starting point. – Daros7 Aug 01 '21 at 15:38
  • What you describe is "fixed offset", not "fixed address". There is no standard way to do this. The standard doesn't even have the concept of a "linker". – Raymond Chen Aug 01 '21 at 15:44
  • @RaymondChen So how could it be that in case of dll's exported functions the addresses is "fixed" - the calling program precisely knows a what address the imported from dll function is? – Daros7 Aug 02 '21 at 11:25
  • DLLs are not covered by the C++ standard, so they are allowed to use nonstandard techniques. (Note that DLL addresses are not "fixed"; they are calculated at runtime and can change from run to run.) – Raymond Chen Aug 02 '21 at 13:48
  • @RaymondChen One question more. Having a compiled file (an exe) am I right that the function offsets are always fixed and written into the pe? I'm asking that because i have some 3-rd party program that works on some exe file and utilizes the function offsets as constant, fixed values. – Daros7 Aug 03 '21 at 21:13