0

I'm calling a function with __func__ as one of the parameters so I can store the name of the function calling that function without having to retype the name of the calling function.

Is there a way of also getting the address of the calling function - a sort of getaddress(__func __) ??

melpomene
  • 84,125
  • 8
  • 85
  • 148
Mike Bryant
  • 310
  • 2
  • 12
  • In standard C++, no way. Using deep assembly-level nonstandard hackery, possibly. But that's way out of my area of expertise. – Silvio Mayolo Mar 18 '19 at 23:51
  • 2
    Your question title suggests that you want the address of the `__func__` character array -- which the expression `__func__` already gives you. But I think what you really want is a function pointer value that is the address of the calling function. You're not going to get that from `__func__`, which is just a static character array. – Keith Thompson Mar 18 '19 at 23:57
  • yes I found a few hackery ways of doing it but they are very implementation dependent. – Mike Bryant Mar 18 '19 at 23:59
  • yes - I want an address I can call. The example was just to illustrate what I am effectively after. – Mike Bryant Mar 19 '19 at 00:00
  • I don't think that information is stored anywhere, even if you were to use asm directly. – melpomene Mar 19 '19 at 00:05
  • It's not stored directly - but it's the address two back on the stack minus the call itself minus the calling overhead. I was hoping there was some way to avoid calculating it using assembly as of course with different compilers there might be slightly different stack pushes. – Mike Bryant Mar 19 '19 at 00:09
  • What do you mean by "minus the calling overhead"? The only thing on the stack is a return address, which has no direct relation to the beginning of a function. – melpomene Mar 19 '19 at 00:14
  • If you call a function with parameters, those go on the stack as well. The compiler knows how far back it put the actual return address but no way a user can know this. And yes - it's the return address that is stored but if you place the call as the first function you can work back from there. But major hack I'm trying to avoid – Mike Bryant Mar 19 '19 at 00:28

3 Answers3

0

The address will not tell you much; may I instead suggest the predefined macros __FILE__ and __LINE__? They will tell you the current source file (as a char*) and the current line. When you call a function passing those as parameters, you'd know which file/line was the function called from.

They're evaluated by the compiler at the point of usage. If you use them inside the function as opposed to passing them as parameters, they'll tell you the file/line of the function itself.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • I'm not trying to use them as some sort of debug. I'm trying to build a table of calls without explicitly re-typing function names twice. – Mike Bryant Mar 18 '19 at 23:56
  • Compile with .map file creation, parse the map file. The C++ names will be mangled though. The map file is poor man's debug symbols... – Seva Alekseyev Mar 19 '19 at 01:35
0

You can declare function pointers and then assign specific functions to them. So then you could have an array or other collection of such pointers as your table.

If this works for you and you accept the answer, I'm willing to come back and create a short summary here. (I know I'm not supposed to answer with just-a-link.) But see if this approach will do what you want. https://www.learncpp.com/cpp-tutorial/78-function-pointers/

Anne Gunn
  • 2,347
  • 1
  • 28
  • 42
0

There is no portable standard C++ way to do this. You could use compiler/OS specific hacks, the same was as in C, but it's less useful in C++ since it only works on extern "C" names (where the __FUNCTION__/__func__ match what dlsym expects).

Since that hack only works on extern "C" names, this means you can't use it for templated functions, class methods, or function overloading (same function name, different argument prototypes), which is fairly restrictive. Mind you, even typing out the function name wouldn't work in some of those cases already (e.g. the name alone doesn't describe the prototype, so function overloading wouldn't work).

I think you need to rethink a design that's essentially demanding reflection in C++; the nature of optimizing compilers is that most of the functions you define don't actually have to exist, or if they do, they exist only with names that are meaningless to anything but the compiler. When you ask to dynamically determine the address of the current function from within the function, you're assuming the function exists, with an actual address, in the final compiled binary, when it could just as easily have been inlined into each actual call site, partially merged with a near identical function, etc.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271