[comp.lang.c] Can a subfunction find the name of the calling function?

woo@acf4.UUCP (Alex C. Woo) (04/29/87)

Is there anything comparable to getarg and iargc for subroutines
or functions?  How can a function determine the name of the function
which calls it or the number of calling arguments, either in C
or f77?

Alex Woo
woo@acf4.nyu.edu
wooa@nyuacf.bitnet
seismo!cmcl2!acf4!woo

gwyn@brl-smoke.UUCP (05/01/87)

In article <12620001@acf4.UUCP> woo@acf4.UUCP (Alex C. Woo) writes:
>Is there anything comparable to getarg and iargc for subroutines
>or functions?  How can a function determine the name of the function
>which calls it or the number of calling arguments, either in C
>or f77?

Since none of the source code symbols are necessarily around
at run time, in general the names of functions are not available
at run time.

There is no built-in way to determine number of arguments, either.
Once upon a time there was a nargs() function for this, but it
really just returned the parameter stack size in words, not the
number of arguments (which is harder).  I don't know what good
either one would do in the general case.

The bottom line is, "no, you can't do that, at least not portably".

ramin@scampi.UUCP (05/06/87)

In article <12620001@acf4.UUCP>, woo@acf4.UUCP (Alex C. Woo) writes:
> 
> Is there anything comparable to getarg and iargc for subroutines
> or functions?  How can a function determine the name of the function
> which calls it or the number of calling arguments, either in C
> or f77?
> 
> Alex Woo

Here's one way of getting the function name. It might not appeal to some
people's aesthetic, but it works... (I recall seeing something like it
in GNU emacs in the form of DEFUN but it's been a while (:-) 
(more commentary at the end...)

***************************************************************************

#define	CALL1(func,a) 			func("func",a)
#define	CALL2(func,a,b)			func("func",a,b)
#define	CALL3(func,a,b,c)		func("func",a,b,c)
#define	SUB1(func,a)			func(name,a) char *name;

main()
{
  CALL3(first,1,2,3);
  CALL1(foo,"this is a parameter");
}

first(name,x,y,z)
char	*name;
int	x,y,z;
{
  printf("%s - %d - %d - %d\n",name,x,y,z);
}

SUB1(foo,text)
char	*text;
{
  printf("%s -- %s\n",name,text);
}
***************************************************************************

It was used in one project to print out debugging and manual traceback
information out... It was actually used within the following context...

#ifndef TRACEBACK
#define	CALL1(func,a)	func(a)
#else
#define	CALL1(func,a)	log_name(func);	func("func",a)
#endif

Where log_name would be a function that would write something like
"Entering function: foo at [time/date]" to a temporary log-file.

Taking out TRACEBACK would just force cpp to generate normal code
without all the strings and function calls... In fact, the source to
the log_name function would not even be #include'd if TRACEBACK was
undefined... It's a fairly painless insurance policy for way down the line...

Nobody complained after the first time they checked out the
log-file to see where their programs had gone to pieces. Especially
when you get one of those intermittent bugs that happen after
8 hours of crunching in real-time... (especially if it doesn't happen
in BSD (Ultrix) but does in VMS... Yow!)
Most people, in fact, customized the macro's to print out further 
logging info... some got carried away... But that's another story (;-)

This stuff was tested on Ultrix, Sun, and VAX/VMS... Your mileage may
vary... caveat emptor...

'nuff said...

r...
 

-- 

(insert-file ".disclaimers")

ramin firoozye'			{ihnp4,lll-lcc,hoptoad}!scampi!ramin
systems control inc.		(415) 494-1165 x-1777
1801 page mill road
palo alto, ca  94304
*** Wars are not fought to decide who is right... Only who is left... ***