Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > function name from function pointer

Reply
Thread Tools

function name from function pointer

 
 
Alessandro Basili
Guest
Posts: n/a
 
      11-04-2010
On 11/3/2010 10:58 PM, Jorgen Grahn wrote:
> On Wed, 2010-11-03, Alessandro Basili wrote:
>> On 11/3/2010 1:40 PM, Alessandro Basili wrote:
>>> Dear all, I have been looking for a way to print the function
>>> name (as I name it in my source code) via the function pointer. I
>>> have been asking the "oracle" (i.e. google) and a lot of forums
>>> suggested a very broad range of semi-solutions through ldaddr
>>> (not POSIX and using dynamic linking) or backtrace and some
>>> braver ones which attempted to "maintain" a table of pointers and
>>> names.
>>>

>>
>> Apparently I haven't looked as thoroughly as I thought.
>>
>> http://c-faq.com/index.html FAQ 20.6
>>
>> Although the idea of maintaining my own table I found it quite
>> awkward.

>
> Judging from your three postings, you seem to believe you have a
> right to demand this functionality from the language. Let me humbly
> point out that most C programmers /don't/ want that feature, and
> you're unlikely to get it.
>

I must have erroneously under-evaluated the complexity of the problem,
and by no means I believe I have a right to demand anything.
The post was initiated when I bumped into this problem and started
looking around if somebody else had already had the same urge (i.e.
printing the name of a function knowing its pointer). As I can see it
now, is not such a common problem that would worth the effort of a
language implementation change.

> What are you trying to accomplish? Perhaps there is a solution to
> your problem which doesn't involve knowing the names of your
> functions.
>


I have implemented a state machine, using pointers to function for
states. The dispatcher provides events to the states and a change in the
state is simply accomplished changing the "state" pointer to yet another
function (the layout of the program can be found here:
http://www.netrino.com/Embedded-Syst...Driven-Systems,
in listing 1,2 and 3).

I found the approach quite nice and easily scalable to more complex
problems, without having the need to maintain any table (events, states)
or the burden of so many switch/case scattered around.

My problem though is that in this approach is not quite easy to print in
which state I am, since the state is represented only by the function
pointer. That is why I thought that having the possibility to get the
name of the function from its pointer would have helped me out.

> /Jorgen
>


 
Reply With Quote
 
 
 
 
Alessandro Basili
Guest
Posts: n/a
 
      11-04-2010
On 11/3/2010 8:06 PM, Jens Thoms Toerring wrote:
....
>
> On the other hand there's already all the infrastructure for mapping
> function names to addresses when you compile with debugging support.
> And on many platforms there are more or less well-documented ways to
> get at this informa- tion which the debugger is using. But, of
> course, this isn't standardized by the C standard - if it were each
> program would always have to be compiled in debug mode and C could
> only be used on platforms where the linker can be made to create
> such a map between function names and addresses - and that for a
> minority of cases where this information is of any interest.
>

Since the projects I'm working on are never so big, I believe that if I
have to use a debugger that is already a sign that something is
basically wrong in the structure of the program, so wrong that I cannot
see it simply looking at the code. And I also believe that getting use
to debuggers is also a bad habit since it will not be there when the
program is crashing suddenly and there are no logging information to
trace at that stage (but this is OT).

> Your best bet is probably to check for the platforms your program is
> to be used on if there is some support to get at the debugging
> information from within your program. Unfortunately, this is rather
> likely to be platform-dependent but may still be the most painless
> way to get at such a mapping. I would guess that it's going to be
> described in the documentation for the lin- ker and the format of
> the executable files produced. And on e.g. Linux you simply could
> parse the output of a utility like 'objdump' which gives you all the
> infor- mation required in a rather simple to parse text format.
> Other systems may have similar tools.
>


Thanks for the hint, that means that I would need to declare+define the
functions in yet another file, in order to have an object file to link
against. If the functions are already residing in the same file as my
main then objdump will not help me much, correct?
> Regards, Jens


 
Reply With Quote
 
 
 
 
Niklas Holsti
Guest
Posts: n/a
 
      11-04-2010
Alessandro Basili wrote:
> On 11/3/2010 10:58 PM, Jorgen Grahn wrote:
>>> On 11/3/2010 1:40 PM, Alessandro Basili wrote:
>>>> Dear all, I have been looking for a way to print the function
>>>> name (as I name it in my source code) via the function pointer...


>> What are you trying to accomplish? Perhaps there is a solution to
>> your problem which doesn't involve knowing the names of your
>> functions.

>
> I have implemented a state machine, using pointers to function for
> states. The dispatcher provides events to the states and a change in the
> state is simply accomplished changing the "state" pointer to yet another
> function ...
>
> My problem though is that in this approach is not quite easy to print in
> which state I am, ...


It seems that all these function pointers have the same type, which
makes it easier.

You could represent the state by a struct that contains both the
function pointer and a *char to the (constant) name of the function.

If you feel that it is too heavy to change two pointers (the above
struct) when the state changes, you could make an additional level of
indirection and represent the state by a pointer to a struct that
contains the function pointer and the function name.

HTH,

--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      11-04-2010
Nick <(E-Mail Removed)> writes:

> Alessandro Basili <(E-Mail Removed)> writes:
>
>> Dear all,
>> I have been looking for a way to print the function name (as I name it
>> in my source code) via the function pointer.
>> I have been asking the "oracle" (i.e. google) and a lot of forums
>> suggested a very broad range of semi-solutions through ldaddr (not
>> POSIX and using dynamic linking) or backtrace and some braver ones
>> which attempted to "maintain" a table of pointers and names.
>>
>> Did anybody ever find a more elegant (and portable) solution?
>>
>> p.s.: __func__ is not what I'm looking for, since it is defined when
>> entering the function.

>
> At the point in the source that you create the function pointer you must
> have the name of the function.
>
> So if you replace
> funcp = myfunc;
> with
> funcp = FUNCTION_POINTER(myfunc);
> where funcp is a macro, something like (untested):
> #define FUNCTION_POINTER(f) while(0) {add_to_list(#f,(cast)f); f}


You probably meant to write 'do { ... } while (0)' here. 'while (0)'
prevents the body from being executed and gains nothing in terms of
trailing semicolons (which is the main purpose of the 'do { ... } while
(0)' idiom). However, those are all solutions when you need a macro
that is syntactically a statement. Here you need an expression --
writing 'f' at the end of a loop body will not deliver 'f' as the value
assigned to 'funcp'. In short:

#define FUNCTION_POINTER(f) (add_to_list(#f,(cast)(f)), (f))

> where add_to_list maintains a global list of function pointer/string
> pairs, then later you can have a function to interrogate that list and
> return the name. A bit expensive - particularly if you take pointer
> addresses in loops (some hoisting may be required).
>
> (cast) is to some sort of generic function pointer. You need a greater
> C expert than myself to tell you if it is guaranteed that a pointer to
> one type of function, cast to another, will always match itself cast in
> the same way later, and that no two will end up the same.


Yes, that is safe.

The overall solution might be rather intrusive, but with little to go on
as to what the overall problem is, it's hard to know what is or is not
suitable.

--
Ben.
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      11-04-2010
"Alessandro Basili" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 11/3/2010 10:58 PM, Jorgen Grahn wrote:


>> What are you trying to accomplish? Perhaps there is a solution to
>> your problem which doesn't involve knowing the names of your
>> functions.
>>

>
> I have implemented a state machine, using pointers to function for
> states. The dispatcher provides events to the states and a change in the
> state is simply accomplished changing the "state" pointer to yet another
> function (the layout of the program can be found here:
> http://www.netrino.com/Embedded-Syst...Driven-Systems,
> in listing 1,2 and 3).
>
> I found the approach quite nice and easily scalable to more complex
> problems, without having the need to maintain any table (events, states)
> or the burden of so many switch/case scattered around.
>
> My problem though is that in this approach is not quite easy to print in
> which state I am, since the state is represented only by the function
> pointer. That is why I thought that having the possibility to get the
> name of the function from its pointer would have helped me out.


I didn't quite understand the example in your link.

But, why can't you have an extra attribute (in the example, where it says
"... extra attributes of Keyboard"), which stores the current state as an
enumeration, or, if you prefer, as the actual name of the handler function,
or just as any string you like.

Then whenever you have FsmTrans_, you arrange for this attribute to change.

Then you can access the current state (perhaps using an extra Fsm- function)
in a form more meaningful than the machine address of the function pointer.

(Or perhaps, if I've understand properly, you can turn this around, so that
state is described by an enumeration anyway, rather than a function pointer,
in struct Fsm, and this number is used to pick up the corresponding function
pointer from a table for dispatching.

This will be a table containing the addresses of the 3 or 4 handlers; If the
same Fsm code is used elsewhere, then you might need the address of the
table itself in Fsm, or perhaps the table can itself be part of Fsm, if the
size is limited.)

--
Bartc

 
Reply With Quote
 
Alessandro Basili
Guest
Posts: n/a
 
      11-04-2010
On 11/4/2010 3:35 PM, BartC wrote:
> But, why can't you have an extra attribute (in the example, where it says
> "... extra attributes of Keyboard"), which stores the current state as an
> enumeration, or, if you prefer, as the actual name of the handler function,
> or just as any string you like.


On 11/4/2010 11:22 AM, Niklas Holsti wrote:
> You could represent the state by a struct that contains both the
> function pointer and a *char to the (constant) name of the function.



Indeed this is what I ended up with before the whole idea bumped into my
mind and I believe I will come back to that.

> (Or perhaps, if I've understand properly, you can turn this around, so
> that state is described by an enumeration anyway, rather than a function
> pointer, in struct Fsm, and this number is used to pick up the
> corresponding function pointer from a table for dispatching.


The reason why I don't wanted to deal with an enumeration description
_and_ a table for dispatching is that I will need to maintain two
"lists", first the enumeration and second the table of correspondences
otherwise I will have problems. Given my attitude in writing code, I
tend to minimize the number of "multiple" representation of an object in
order not to be tied to "multiple" editing whenever I need to add or
remove a part of it.

 
Reply With Quote
 
Joachim Schipper
Guest
Posts: n/a
 
      11-04-2010
Alessandro Basili <(E-Mail Removed)> wrote:
> Dear all,
> I have been looking for a way to print the function name (as I name it
> in my source code) via the function pointer.
> I have been asking the "oracle" (i.e. google) and a lot of forums
> suggested a very broad range of semi-solutions through ldaddr (not POSIX
> and using dynamic linking) or backtrace and some braver ones which
> attempted to "maintain" a table of pointers and names.
>
> Did anybody ever find a more elegant (and portable) solution?
>
> p.s.: __func__ is not what I'm looking for, since it is defined when
> entering the function.


This is in no way general, but something like the code below (warning:
not even compiled!) is a portable solution for those cases where you
know which functions are likely to end up pointed at...

const char *func_name;
int funca(int x) {
if (x == 0) {
func_name = __func__;
return 0;
}

return x;
}

int funcb(int x) {
if (x == 0) {
func_name == __func__;
return 0;
}

return -x;
}

int main(void) {
int (*my_func)(int) = funca;

my_func(0);
printf("Function: %s\n", func_name);
return 0;
}

That said, I'm fairly certain you're trying to do something that is not
a good idea - this is pretty much *only* useful for debugging, and any
decent debugger will already have this functionality built in...

Joachim
 
Reply With Quote
 
Mark Wooding
Guest
Posts: n/a
 
      11-04-2010
Alessandro Basili <(E-Mail Removed)> writes:

> The reason why I don't wanted to deal with an enumeration description
> _and_ a table for dispatching is that I will need to maintain two
> "lists", first the enumeration and second the table of correspondences
> otherwise I will have problems. Given my attitude in writing code, I
> tend to minimize the number of "multiple" representation of an object
> in order not to be tied to "multiple" editing whenever I need to add
> or remove a part of it.


There's a fairly standard macro trick for dealing with this sort of
thing. It effectively encodes a list as a higher-order function for
mapping a given function over the elements of the list.

#define TABLE(_) \
_(TAGA, funca) \
_(TAGB, funcb) \
/* ... */

enum {
#define ENUM(tag, func) STATE_##tag,
TABLE(ENUM)
#undef ENUM
STATE_LIMIT
};

struct {
void (*func)(info *i, /*stuff*/);
const char *name;
} statetab[] = {
#define ENTRY(tag, func) { func, #func },
TABLE(ENTRY)
#undef ENTRY
};

Now things can't get out of sync. If there's some systematic
relationship between the enum tags and function names then you can
encode this in the macros ENUM and ENTRY, and simplify the main TABLE
macro further.

-- [mdw], who enjoys preprocessor games too much.
 
Reply With Quote
 
Nick
Guest
Posts: n/a
 
      11-04-2010
Ben Bacarisse <(E-Mail Removed)> writes:

> You probably meant to write 'do { ... } while (0)' here. 'while (0)'
> prevents the body from being executed and gains nothing in terms of
> trailing semicolons (which is the main purpose of the 'do { ... } while
> (0)' idiom). However, those are all solutions when you need a macro
> that is syntactically a statement. Here you need an expression --
> writing 'f' at the end of a loop body will not deliver 'f' as the value
> assigned to 'funcp'. In short:
>
> #define FUNCTION_POINTER(f) (add_to_list(#f,(cast)(f)), (f))


I did mean all of that. I plead early morning.
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      11-04-2010
"Alessandro Basili" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 11/4/2010 3:35 PM, BartC wrote:


>> (Or perhaps, if I've understand properly, you can turn this around, so
>> that state is described by an enumeration anyway, rather than a function
>> pointer, in struct Fsm, and this number is used to pick up the
>> corresponding function pointer from a table for dispatching.

>
> The reason why I don't wanted to deal with an enumeration description
> _and_ a table for dispatching is that I will need to maintain two "lists",
> first the enumeration and second the table of correspondences otherwise I
> will have problems. Given my attitude in writing code, I tend to minimize
> the number of "multiple" representation of an object in order not to be
> tied to "multiple" editing whenever I need to add or remove a part of it.


You mean, maintaining the correspondence between an enumeration list, and
any associated values?

I have exactly the same problem, and I use a special approach: I use a
separate data file for a project, consisting of sections like this:

table statecodes statenames statefunctions
st1 "state1" &fn_state1
st2 "state2" &fn_state2
st3 "state3" &fn_state3
end

This is processed by a utility program, which creates a header containing
the enumerated values enum{st1=1, st2, st3}, and the arrays statenames[] and
statefunctions[].

Then entries can be modified, added, deleted or moved very easily, and
everything stays in sync (usually the entries aren't numbered like this
example).

(Where functions are involved, and there lots of them, then I would also run
a program which picked these out and created prototype declarations. On one
project, adding one special kind of function involves changes to
half-a-dozen associated tables and headers, which would be a nightmare to do
by hand. Getting them wrong would also give errors hard to track down.)

--
Bartc

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointer to an array vs pointer to pointer subramanian100in@yahoo.com, India C Programming 5 09-23-2011 10:28 AM
Pointer to pointer or reference to pointer A C++ 7 07-05-2011 07:49 PM
Pointer to pointer Vs References to Pointer bansalvikrant@gmail.com C++ 4 07-02-2009 10:20 AM
passing the address of a pointer to a func that doesnt recieve a pointer-to-a-pointer jimjim C Programming 16 03-27-2006 11:03 PM
Pointer-to-pointer-to-pointer question masood.iqbal@lycos.com C Programming 10 02-04-2005 02:57 AM



Advertisments