suppose i have 3 functions:
a()
b()
and c()
both a() and b() can called c(). if function c() is called how do i know who is the caller??

You dont', and you shouldn't. c() should not care who called it, but just do its job and return the results (if any) to the caller.

actually i just made a code in which i need to know who's the caller but later i managed the alternate way to solve my problem.
but still i wanna know whos is the caller..???

You can pass the name of the caller into the callee:

void a(const char *caller)
{
    printf("%s called from %s\n", __func__, caller);
}

void b(const char *caller)
{
    printf("%s called from %s\n", __func__, caller);
    a(__func__);
}

int main(void)
{
    b(__func__);
    return 0;
}

The above code uses C99's predefined __func__ for simplicity. In compilers that don't support it, you'll have to come up with your own naming convention and pass string literals.

There are techniques for building a call-tree by judicious use of macros, so in your code you can do something like this:

#ifdef DEBUG
#define MAX_TREE_DEPTH 10000
size_t ct_level = 0;
const char* call_tree[MAX_TREE_DEPTH];

#define CALLTREE_ENTER call_tree[ct_level++] = __func__;
#define CALLTREE_EXIT  call_tree[ct_level--] = 0;
#else
#define CALLTREE_ENTER
#define CALLTREE_EXIT
#endif /* DEBUG */

void a(void)
{
#ifdef DEBUG
  printf("a() called from %s\n", call_tree[ct_level - 1]);
#endif
}


void b(void)
{
#ifdef DEBUG
  printf("b() called from %s\n", call_tree[ct_level - 1]);
#endif

  CALLTREE_ENTER
  a();
  CALLTREE_EXIT
}

int main(void)
{
   CALLTREE_ENTER
   b();
   CALLTREE_EXIT
   return 0;
}

Now, if you haven't compiled your code for debugging, this will have no performance impact upon you, but if you did, you get the call tree output.

I leave it as an exercise to the poster to add the macro needed so you can eliminate the #ifdef DEBUG blocks in the functions, so you could do something like this:

PRINT_CALLER(__func__);

instead if debugging is on.

This article has been dead for over six months. Start a new discussion instead.