[comp.std.c] Question about ANSI preprocessor

diamond@csl.sony.co.jp (Norman Diamond) (09/26/89)

According to the ANSI standard, does the following code cause
expansion of the preprocessor macro "huh"?

#define huh(x) (abc + (x))

y = huh
#if 0
	, a, lot, of, garbage
#endif
(z);

--
-- 
Norman Diamond, Sony Corporation (diamond@ws.sony.junet)
  The above opinions are inherited by your machine's init process (pid 1),
  after being disowned and orphaned.  However, if you see this at Waterloo or
  Anterior, then their administrators must have approved of these opinions.

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/28/89)

In article <10879@riks.csl.sony.co.jp> diamond@ws.sony.junet (Norman Diamond) writes:
>According to the ANSI standard, does the following code cause
>expansion of the preprocessor macro "huh"?

No, as a general design principle the preprocessor is not required to
back up, apart from the quite limited case of rescanning the
replacement buffer.

dfp@cbnewsl.ATT.COM (david.f.prosser) (09/28/89)

In article <10879@riks.csl.sony.co.jp> diamond@ws.sony.junet (Norman Diamond) writes:
>According to the ANSI standard, does the following code cause
>expansion of the preprocessor macro "huh"?
>
>#define huh(x) (abc + (x))
>y = huh
>#if 0
>	, a, lot, of, garbage
>#endif
>(z);

The invocation of a function-like macro requires that the next
preprocessing token after the macro name be the (.  Thus the
above example must produce the equivalent of

	y = huh (z);

after preprocessing.

Dave Prosser	...not an official X3J11 answer...

scjones@sdrc.UUCP (Larry Jones) (09/29/89)

In article <10879@riks.csl.sony.co.jp>, diamond@csl.sony.co.jp (Norman Diamond) writes:
> According to the ANSI standard, does the following code cause
> expansion of the preprocessor macro "huh"?
> 
> #define huh(x) (abc + (x))
> 
> y = huh
> #if 0
> 	, a, lot, of, garbage
> #endif
> (z);

No.  Section 3.8.3 (Macro replacement) talks about function-like
macros and says:

	Each subsequent instance of the function-like macro name
	followed by a ( as the next preprocessing token
	introduces the sequence of proprocessing tokens that is
	replaced by the replacement list in the definition (an
	invocation of the macro).

In this case, the preprocessing token following the macro name is
"#" rather than "(", so it is not eligable for expansion.
----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@SDRC.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"I have plenty of good sense.  I just choose to ignore it."
-Calvin

diamond@csl.sony.co.jp (Norman Diamond) (10/02/89)

In article <11163@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:

>... as a general design principle the preprocessor is not required to
>back up, apart from the quite limited case of rescanning the
>replacement buffer.

Thank you for answering my question, but I think that your answer might
be a bit too broad.  Section 3.8.3.4 (Dec. 7 '88) says that after
replacement, the replacement buffer must be rescanned WITH THE REST OF
THE SOURCE FILE'S PREPROCESSING TOKENS.

For example, consider:

  #include <stdio.h>
  #define mf1(x) printf("Hello, world.\n")
  #define m2     (z);
  main(){
    mf1 m2
  }

After "m2" changes into "(z);", it must be rescanned with the rest of
the source file's preprocessing tokens.  At this time mf1 must be
recognized as a function-like macro call.  The preprocessor MUST BACK
UP EARLIER THAN THE REPLACEMENT BUFFER.

I will bet that every pre-ANSI compiler/preprocessor would have
rejected the above program.  But ANSI requires it to print
"Hello, world.\n".

In fact I think I can construct a few perverse macros, which will make
the preprocessor take EXPONENTIAL TIME in proportion to the length of
the program.

-- 
Norman Diamond, Sony Corp. (diamond%ws.sony.junet@uunet.uu.net seems to work)
  The above opinions are inherited by your machine's init process (pid 1),
  after being disowned and orphaned.  However, if you see this at Waterloo or
  Anterior, then their administrators must have approved of these opinions.

pardo@cs.washington.edu (David Keppel) (10/13/89)

[Sorry for the post, e-mail bounced.]

diamond@riks. (Norman Diamond) writes:
 >For example, consider:
 >
 >  #include <stdio.h>
 >  #define mf1(x) printf("Hello, world.\n")
 >  #define m2     (z);
 >  main(){
 >    mf1 m2
 >  }
 >
 >I will bet that every pre-ANSI compiler/preprocessor would have
 >rejected the above program.  But ANSI requires it to print
 >"Hello, world.\n".

I tried this on gcc v 1.36/VAX with the `-ansi' flag and got `m2 (z)'.
Should I be filing a bug report?  `gcc' is generally pretty robust
about such things...

 >In fact I think I can construct a few perverse macros, which will make
 >the preprocessor take EXPONENTIAL TIME in proportion to the length of
 >the program.

That should make an interesting submit to the Obfuscated C contest!

	;-D on  ( What do you mean, `non-obfuscated C' ?-)  Pardo
-- 
		    pardo@cs.washington.edu
    {rutgers,cornell,ucsd,ubc-cs,tektronix}!uw-beaver!june!pardo