[comp.lang.c] Incrementing of preprocessor symbols

deller@vrdxhq.UUCP (04/16/87)

Help please. We have a program in which we would like to use something like:

  assert( <expr> ) ;

and have it expand to

  if ( ! <expr> ) error_call( <n>, __FILE__, __LINE__ ) ;

(the __FILE__ and __LINE__ are preprocessed into a quoted string that is the 
filename being compiled, and an integer that is the line number, in the source,
where the symbol appears).

Everything is quite easy to do with a #define, except the handling of <n>.  We
would like the <n> to increment with each expansion encountered in the source,
i.e. with each "assert" in the text.  The <n> helps distinguish the different 
assertions on VMS, where C does not expand __FILE__ and __LINE__ as it does on 
Sun, Sequent, VAX UNIX, and VAX Ultrix.

So, the problem is how to get an <n> that increments with each usage in the
source.  Note that <n> should NOT be incremented each time the statment is
encountered during execution; a lexical increment is desired.

We are not looking to use a pre-preprocessor that modifies the sources as they 
are fed to the "cc" command (piping the source messes up __FILE__, and we can't
afford the extra time to make file copies); we are looking for a solution 
entirely within the C preprocessor.

I would note that any self-respecting macro facility for any assembler can do 
this sort of thing with its eyes closed and one macro expansion behind its 
back.  If as I am beginning to suspect, this is not possible with C, then 
perhaps the C standards committee might take note.

Steven Deller
-- 
<end_message> ::= <disclaimer> | <joke> | <witty_saying> | <cute_graphic>
{verdix,seismo,umcp-cs}!vrdxhq!deller

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/16/87)

In article <3424@vrdxhq.UUCP> deller@vrdxhq.UUCP (Steven Deller) writes:
>I would note that any self-respecting macro facility for any assembler can do 
>this sort of thing with its eyes closed and one macro expansion behind its 
>back.  If as I am beginning to suspect, this is not possible with C, then 
>perhaps the C standards committee might take note.

As you surmised, it is not possible to generate unique labels like
this in the course of C preprocessor macro expansion.  The X3J11
committee is aware of it, but haven't been persuaded that increasing
the power of C's macro processing is sufficiently worthwhile to
counter the fact that some code would break due to the change.

Dave Prosser among others has come up with some very nice proposals
for more powerful and/or flexible C preprocessing, and a number of
X3J11 committee members favor the idea, but not enough to get it
into the standard.

Most people who really need this facility use a separate processor,
such as UNIX's "m4", before compilation.  It's pretty easy to have
"make" add processing like this to the compilation phase.

tps@sdchem.UUCP (04/17/87)

In article <3424@vrdxhq.UUCP> deller@vrdxhq.UUCP (Steven Deller) writes:
>Help please. We have a program in which we would like to use something like:
>
>  assert( <expr> ) ;
>
>and have it expand to
>
>  if ( ! <expr> ) error_call( <n>, __FILE__, __LINE__ ) ;
>
>Everything is quite easy to do with a #define, except the handling of <n>.  We
>would like the <n> to increment with each expansion encountered in the source,
>i.e. with each "assert" in the text.  The <n> helps distinguish the different 
>assertions on VMS, where C does not expand __FILE__ and __LINE__...

The only preprocessor variables are __FILE__ and __LINE__
-- you're out of luck.

>We are not looking to use a pre-preprocessor that modifies the sources as they 
>are fed to the "cc" command (piping the source messes up __FILE__, and we can't
>afford the extra time to make file copies);...

Do what cpp does -- use the
	
	# line NNN FILENAME

directive.  No file copies are necessary, and __LINE__ and __FILE__ should be
updated.

>we are looking for a solution entirely within the C preprocessor.

I agree this would be more desirable, even with the "#line" directive.

>If as I am beginning to suspect, this is not possible with C, then 
>perhaps the C standards committee might take note.

"__FILE__" and "__LINE__" are already in the standard, as
well as "assert(x)".  So you have to come up with another
example to show the usefulness of yet another macro
facility.




--------
# define X	0
# define assert(x)	if ( !x ) _assert( X #= X + 1, __LINE__, __FILE__ );


|| Tom Stockfisch, UCSD Chemistry	tps%chem@sdcsvax.ucsd.edu
					or  sdcsvax!sdchem!tps

guy%gorodish@Sun.COM (Guy Harris) (04/17/87)

>Everything is quite easy to do with a #define, except the handling of <n>.  We
>would like the <n> to increment with each expansion encountered in the source,
>i.e. with each "assert" in the text.  The <n> helps distinguish the different 
>assertions on VMS, where C does not expand __FILE__ and __LINE__ as it does
>on Sun, Sequent, VAX UNIX, and VAX Ultrix.

Tell DEC to get with the program and implement __FILE__ and __LINE__
under VMS before they are forced to by requirements for ANSI C
conformance.

henry@utzoo.UUCP (Henry Spencer) (04/19/87)

> So, the problem is how to get an <n> that increments with each usage in the
> source.  Note that <n> should NOT be incremented each time the statment is
> encountered during execution; a lexical increment is desired.
> 
> We are not looking to use a pre-preprocessor... looking for a solution 
> entirely within the C preprocessor.

You are out of luck; there is none that I can see.

> I would note that any self-respecting macro facility for any assembler can do 
> this sort of thing with its eyes closed and one macro expansion behind its 
> back.  If as I am beginning to suspect, this is not possible with C, then 
> perhaps the C standards committee might take note.

The C standards committee has been most explicit, as I recall, that the C
preprocessor is not a general-purpose macro processor and they have no
intention of turning it into one.  If somebody had actually implemented
something like this, used it, and found it workable, in *C* and not some
other random language, they might consider it (maybe; it's a bit late).
That aside, it just requires too much invention and is too great a
departure from existing C experience.  The ANSI C committee is not in the
business of making C all things to all users; despite some ill-advised (in
my personal opinion) changes, they are basically standardizing an existing
language rather than inventing a new one.
-- 
"If you want PL/I, you know       Henry Spencer @ U of Toronto Zoology
where to find it." -- DMR         {allegra,ihnp4,decvax,pyramid}!utzoo!henry

nw@amdahl.UUCP (04/28/87)

In article <3424@vrdxhq.UUCP>, deller@vrdxhq.UUCP (Steven Deller) writes:
> I would note that any self-respecting macro facility for any assembler can do 
> this sort of thing with its eyes closed and one macro expansion behind its 
> back.  If as I am beginning to suspect, this is not possible with C, then 
> perhaps the C standards committee might take note.

The committee has considered and rejected ideas like this a number of
times.  There are two reasons usually given:  Lack of "prior art"--the
committee's charter is to codify existing practice, NOT to define a new
language and call it "C".  I know that hasn't always held us back but
that's another story :-)  The other reason is that environments that
support a C compiler usually also support good stand alone macro
facilities such as m4 in UN*X.

The opinions expressed above are mine (but I'm willing to share.)

			Regards,
And the sign said               Neal Weidenhofer
   "The words of the prophet    ...{hplabs|ihnp4|seismo|decwrl}!amdahl!nw
Are written on the subway walls Amdahl Corporation
   And tenement halls..."       1250 E. Arques Ave. (M/S 316)
				Sunnyvale, CA 94088-3470
				(408)737-5007