Prototyping in an imperfect world....

Adam Stoller ghoti+ at andrew.cmu.edu
Sat Jun 30 08:58:59 AEST 1990


(lengthy - but lot's of white-space  -- sorry)

Some of this is old news, but some may not be - and I'm a bit interested
in some [reasonable] opinions on either....

[prolog (harmonicas playing in the background?)]
As many of us are aware - there is a wonderful thing called prototyping
-- especially with respect to ANSI-C.  Unfortunately we are also aware
that while some people on some platforms may have full prototyping
abilities others may not -- and this tends to cause problems for people
who'd like to try and make their code portable....

There are two different places where this comes into effect:

1) extern reference declarations
2) function definitions

The first I believe has been reasonably well addressed.  For those not
familliar with a way to easily handle it I provide the following
[possible] definition:

	/* external reference declarations */
	/* use: extern int foo P_((int x, char c, long d)); */
	#ifdef __STDC__
	#define P_(args)    args
	#else
	#define P_(args)    ()
	#endif

A hack? Yes, but a farily clean and reasonable one (IMO).

The second situation however I haven't seen addressed much.  About the
only way I've seen people deal with it was by doing something like:

	int
	#ifdef __STDC__
	foo(int x, char c, long d)
	#else
	foo(x, c, d)
	  int x;
	  char c;
	  long d;
	#endif
	{
	   ....
	}

This, IMO, is both a painful (to implement/maintain) and ugly hack - and
one which I'd like to avoid if possible.

To this end - one of the people I work with came up with the idea for a
macro to use for the definitions - which I'd like to share with you now
and get some opinions on:

	#ifdef __STDC__
	#define	PP_(a)	(
	#define	V_	void)
	#define	S_	,
	#define	E_	)
	#else
	#define	PP_(a)	a
	#define	V_
	#define	S_	;
	#define	E_	;
	#endif

This allows the above example to be defined like:

	int foo PP_((x, c, d))
	  int	x S_	
	  char 	c S_
	  long	d E_
	{
	    ......
	}

Or
	int foo PP_(())
	V_
	{
	    ....
	}

Which for the most part is reasonably close to the old-style definitions
though nevertheless hackish.


[Question Time]

Q-1) Is it too ugly for words  ?
	Personally, I admit not liking the loss of the
	commas/semicolons which are pretty much second-nature when
	typing in the code, but other than that it doesn't bother me
	too much.

Q-2) Is it too hackish to be considered reasonable ?
	I think it stays within the boundary of reasonable hacks
	(whatever that boundary may be, unless you're a purist who
	considers any hack evil??)

Q-3) Is it reasonably maintainable ?
	It suffers a little of the same problem as the earlier #ifdef
	example - in that there are still two places where the name and
	number of arguments must be maintained - but I think this one
	wears a little better in that it's really only as bad(?) as the
	old-style definitions.

Q-4) Can it be made better ?
	Mostly I mean this in terms of the symbols chosen for the
	macros, and possibly the macros themselves.  Certainly there
	are tons of alternatives ("use A_ instead of S_", etc) - but
	I'm looking for something a bit more substantial, with
	reasonable explanation. (hey, it's always possible that we
	might have gotten it "right" the first time....:-)
	
	(FYI: V_ == void, S_ == separator, E_ == end-of-list)



[Visualization]
(some blank lines removed from preprocessor output)
[      | <-column 0]
----------------
    > cat foo.c
    /* #define's as shown above */

        int fname PP_((a1, a2))
        int a1 S_
        int a2 E_
        {
        }

        struct lconv *ansi_localeconv PP_(())
        V_
        {
        }

----------------
    > cc -E -D__STDC__ foo.c
        int fname 	(
        int a1 ,
        int a2 )
        {
        }

        struct lconv *ansi_localeconv 	(
        void)
        {
        }

----------------
    > cc -E -U__STDC__ foo.c
        int fname 	(a1, a2)
        int a1 ;
        int a2 ;
        {
        }

        struct lconv *ansi_localeconv 	()

        {
        }

----------------



More information about the Comp.lang.c mailing list