[net.bugs] Bug

stephenf@elecvax.SUN (Stephen Frede) (05/29/84)

Newsgroups: net.bugs,net.lang.c
Subject: Bug (?) in C preprocessor

Note the following behaviour of the C preprocessor (V7 and System V):

#define FRED jim
#define QUOTE(x) "x"

QUOTE(FRED)
______________________

	The output of the C preprocessor when fed this fragment is

"FRED"

	Obviously, it is applying the QUOTE() macro on FRED,
before re-scanning and since "FRED" is then quoted, no substitution
takes place. If the order of evaluation were the other way, ie to
evaluate what is inside the parentheses first, before applying the
macro QUOTE to it, the result would be

"jim"

	(which is actually what I wanted when I discovered this). I
suggest that this order of evaluation is more sensible, and conforms
more closely to what C itself (and almost all other programming
languages) does (evaluating expressions from within the most deeply
nested level of parentheses first).
	I will probably be changing the preprocessor here to do this,
but would like to see what the net thinks first. Has anyone else
come across this problem?

Aside:
	If this change is made, then it allows constructs like

#define QUOTE(x) "x"
#include QUOTE(NAME.h)

	where NAME is defined to the preprocessor on the command line
at compile time. Whether this is a terrible thing to do or not is
another story. I wanted it so I could modify maketerms.c in the nroff
system so that I could make terminal driving tables one at a time (a
single "make" at the top of our source directory would then install
a new terminal driving table in /usr/lib/terms without having to create
a whole set. Also, new driving tables could then be added without
modifying maketerms.c.


					Stephen Frede
					Dept. Computer Science
					University of NSW
					P.O. Box 1
					Kensington 2033
					AUSTRALIA


				...!decvax!mulga!stephenf:elec70b

boyd@basser.UUCP (05/29/84)

No.  The reference manual states:

	"Each occurrance of an identifier mentioned in the
	formal parameter list of the definition is replaced
	by the corresponding token string from the call."

	"...the replacement string is rescanned for more
	defined identifiers."

	"Text inside a string or character constant is not
	subject to replacement."

Hence:

#define quote(x)	"x"
#define gooeys		sooterkin

quote(gooeys) expands to "gooeys" and not "sooterkin".

I have written a C preprocessor that adheres to the most
recent standard.  The standard has these "additions":

	#elif expression
and
	defined(name) in #if expressions

I wouldn't advise a change to the preproccessor to do this alternate
expansion because by definition it would NOT be the C preproccessor.


---
>From the VB can of Boyd Roberts.	...!decvax!mulga!boyd:basser

stephenf@elecvax.UUCP (05/29/84)

>   From: boyd@basser.SUN (Boyd Roberts)
>   References: <204@elecvax.SUN>
>   Organization: Dept of C.S., University of Sydney
>   
>   No.  The reference manual states:
>   
>   	"Each occurrance of an identifier mentioned in the
>   	formal parameter list of the definition is replaced
>   	by the corresponding token string from the call."

It also state that subsequent occurrences of identifiers used in
ordinary "#define"s are replaced by the appropriate token-string
wherever they occur. What the manual doesn't specify is any order
for replacement.
    
>    	"...the replacement string is rescanned for more
>    	defined identifiers."

Exactly, but which ones come first?
    
>    	"Text inside a string or character constant is not
>    	subject to replacement."

The identifier is not inside a string or character constant. It happens
to be inside another macro, which may introduce quotes at that point,
when replacement occurs. But not until replacement occurrs.
    
>    Hence:
>    
>    #define quote(x)	"x"
>    #define gooeys		sooterkin
>    
>    quote(gooeys) expands to "gooeys" and not "sooterkin".

Your "hence" does not follow at all.
	quote(gooeys)
may first be expanded to
	quote(sooterkin)
and thence to "sooterkin" in complete accordance with the reference
manual. It's not defined.
    
>    I wouldn't advise a change to the preproccessor to do this alternate
>    expansion because by definition it would NOT be the C preproccessor.

By definition where? Not the C reference manual.
    
					- Stephen Frede
					...!decvax!mulga!stephenf:elecvax

ed@mtxinu.UUCP (05/29/84)

If you change the behaviour of the preprocessor, remember that
C requires that the order of evaluation of expressions be
undefined.  Therefore, depending on any evaluation order
will yield unportable code.

-- 
Ed Gould
ucbvax!mtxinu!ed

guy@rlgvax.UUCP (Guy Harris) (05/30/84)

> I have written a C preprocessor that adheres to the most
> recent standard.  The standard has these "additions":

> 	#elif expression
> and
> 	defined(name) in #if expressions

The former is very nice - I wish it were available in the Reiser "cpp"
that comes with just about every UNIX under the sun.  The latter is actually
in the most recent standard, if the S5 man page CPP(1) is considered the
most recent standard (it also documents __FILE__ and __LINE__).  The
parentheses are optional (shades of the "return(x)" vs. "return x" debate!)
according to CPP(1).

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

vch@rruxd.UUCP (Kerro Panille) (03/10/86)

I found a nasty bug in the MS-C 3.0 compiler the other day, and thought I
would tell everyone who might be interested in it. If you have MS-C 3.0,
give this program a try:

struct a
{
	int b;
};

void
funca( c )
struct a *c;
{ 
	int d= 1000;

	c->b *= 1000.0;  \
	c->b *= d;       /    Either of these lines produces the error
}

Then give the command:

cl -c test.c

You should get:

test.c(nn) : Compiler error (internal):Infinite spill

It seems that the compiler just doesn't like this simple structure. The manual
says that you "should never see this message," and tells you to write to MS
and report the bug. No mention about when you're going to get a fix. Fortunatly,
the work-around is obvious.


-- 
Vince Hatem                           +----------------------------------------+
Bell Communications Research          ! "..., isn't that right, Daniel?"       !
Raritan River Software Systems Center ! "When you get that look on your face,  !
444 Hoes Lane                         !  Marty, I go prune my roses."          !
4D-340                                !                   -Frank Herbert       !
Piscatway, NJ 08854                   !                   Chapterhouse: Dune   !
(201) 699-4869             	      !                   pg 459               !
{rrux?, pyux?, bellcore, topaz,       +----------------------------------------+
       ihnp4}!rruxo!vch