[comp.lang.c] What can I get away with

jfjr@mitre-bedford.ARPA (Jerome Freedman) (06/30/87)

Suppose I declare an array of pointers to functions in one module.
I write a function, in the same module, which will install functions
in this array -call the function "install".

In a different module I write a function, call it "new_function".
I make NO attempt at making "new_function" visible anywhere outside
of the module in which it is written. I call install on this
new_function to put it in my array. If there is an objection to
passing function pointers to functions then I make these function
pointers a component of a structure. Can I then go through this
array of function pointers (or structures containing function
pointers) and call the functions pointed to even if they are not
declared externally (to avoid further confusion all these functions
have no parameters and they return void). What can I get away
with staying within C, what can I get away with without breaking
something?

                                    Jerry Freedman,Jr
                                    jfjr@mitre-bedford.ARPA



Jerry Freedman, Jr       "If at first you don't succeed, lower your standards"
jfjr@mitre-bedford.arpa
(617)271-6248 or 7555    

chris@mimsy.UUCP (Chris Torek) (07/01/87)

In article <8190@linus.UUCP> jfjr@mitre-bedford.ARPA (Jerome Freedman) writes:
>Suppose I declare an array of pointers to functions in one module.
>I write a function, in the same module, which will install functions
>in this array -call the function "install".

>In a different module I write a function, call it "new_function".
>I make NO attempt at making "new_function" visible anywhere outside
>of the module in which it is written.

You have to do something special to make it invisible outside its
own module, namely, declare it `static'.

>I call install on this new_function to put it in my array. ...
>Can I then go through this array of function pointers ... and call
>the functions pointed to even if they are not declared externally
>... ?

Certainly.

	% cat f1.c
	static void (*a[10])();
	static int n_funcs;

	int
	install(f)
		void (*f)();
	{

		if (n_funcs >= sizeof (a) / sizeof (a[0]))
			return (-1);	/* out of space */
		a[n_funcs] = f;
		return (n_funcs++);
	}

	void
	call_all()
	{
		register int i;

		for (i = 0; i < n_funcs; i++)
			(*a[i])();
	}
	% cat f2.c
	/*ARGSUSED*/
	static void
	new_function()
	{

		printf("new_function\n");
	}

	int
	main(argc, argv)
		int argc;
		char **argv;
	{

		(void) install(new_function);
		call_all();
		return (0);
	}
	% cc f1.c f2.c
	% a.out
	new_function
	% 

This assumes your compiler can handle `void (*p[N])()'.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	seismo!mimsy!chris

mpl@sfsup.UUCP (07/01/87)

In article <8190@linus.UUCP>, jfjr@mbunix.UUCP writes:
> Suppose I declare an array of pointers to functions in one module.
	[deleted stuff]
> pointers) and call the functions pointed to even if they are not
> declared externally (to avoid further confusion all these functions

YES, you can!  The only thing is you don't get any sanity checking on the
return value of the function (with K&R flavored C).  Consider

file1.c:

int	(*a[10])();

static next;

install(f)
int	(*f)();
{
	a[next++] = f;
}

gleep()
{
	int	n;
	.
	.
	n = (*a[0])(3);
	.
	.
}

file2.c

char *
foobar()
{
	return NULL;
}

main()
{
	install(foobar);
	gleep();
	.
	.
}

"n" in gleep holds an "int", but (*a[0])(3) returns a char *.
The compiler will not pick up this bug, although lint will.

jfh@killer.UUCP (07/06/87)

In article <8190@linus.UUCP>, jfjr@mitre-bedford.ARPA (Jerome Freedman) writes:
> Suppose I declare an array of pointers to functions in one module.
> I write a function, in the same module, which will install functions
> in this array -call the function "install".
> 
> In a different module I write a function, call it "new_function".
> I make NO attempt at making "new_function" visible anywhere outside
> of the module in which it is written. I call install on this
> new_function to put it in my array. ...
[ Much more stuff deleted ]

You should be able to pass that pointer out of the function, say with the
code

static	void	new_function ()
{
	some_code ;
}

ins_new_func ()
{
	install (new_function);
}

and install should add the pointer to its list.  The reason for all of
these "should"s is there has got to be some machine somewheres that
does something different.  This idea works just fine on every machine
I've seen - but somewheres out there there has to be an overlay linker
or other strange beast that things new_function isn't needed after
ins_new_func goes away.

- John.

Disclaimer:
	This space for rent.