[net.lang.c] PCC compiler question

patc (03/15/83)

	I have come across a funny in the PCC compiler that I would
like to know about. A statement was mis-coded as:

		a && b *= c ;

No error message was given. The code that was produced showed that
the compiler compiled the statement as:

		if ( a ) b *= c ;

I thought the && operator had a higher precedence than assignment
and the result should have been equivalent to:

		( a && b ) *= c ;

If I code the statement with explicit parens then I get the error
message "lvalue required" which is what I expected. Anybody have any
idea why this is like this and is this the way it's suppose to work
or is it a bug? Reply by mail to 
 	[cbsog,decvax,ihnss,puree,ucbvax]!teklabs!tekmdp!patc
	[ucbcad,iddic]!tektronix!patc
	patc@tektronix			CSNET
Thanks.

porges (03/20/83)

#R:bronze:-50100:inmet:5000002:000:490
inmet!porges    Mar 18 17:48:00 1983

	I don't know if you could really call 

	a && b *= c

	(or whatever) a bug.  The precedence levels are confusing, but all
that's happened is that the compiler found a legal parse.  If the legal parse
implies that the default precedence is not applicable, too bad.  The precedence
levels server to disambiguate the parse, not restrict it.  
	Or am I wrong again?
					-- Don Porges
					...harpo!inmet!porges
					...hplabs!sri-unix!cca!ima!inmet!porges
					...yale-comix!ima!inmet!porges

jdd (03/23/83)

The behavior in PCC on:

	a && b *= c

is (possibly) serendipitous but ultimately indicative of a compiler bug.
Parsing it as:

	a && (b *= c)

does not reflect the correct operator precendences.

If you believe that PCC is magically "doing the right thing", tell me why it
won't compile:

	int *a, b, c;

	...

	... a+b[c] ...

since interpreting the expression as:

	... (a+b)[c] ...

would "make sense".  No compilers (i.e., no languages) I know of overload
the syntax in this way; a little thought suggests that doing so could cause
as much harm as good; most of my coding errors have some "interpretation",
but probably not the one I intended.

Cheers,
John ("Let's All Program In Lisp Instead") DeTreville
Bell Labs, Murray Hill

bernie (03/30/83)

Yes, the statement
       a && b *= c;
is a curious thing.  Nevertheless, it makes sense as
       if (a) b *= c;
since the compiler is really regarding it
as
       a && (b *= c);
and will only evaluate the (b *= c) part if the a part is non-zero.
That is, if a is false, there's no need to evaluate the other operand
of && since the overall value of the expression is already known.
				--Bernie Roehl
				...decvax!watmath!watarts!bernie

johnl (04/01/83)

#R:watarts:-176200:ima:15900004:000:680
ima!johnl    Mar 31 11:32:00 1983

Let's drive a stake through the heart of this one, once and for all.

       a && b *= c;                     (1)

should not be the same as:

       if (a) b *= c;                   (2)

because, since && binds tighter than *=, the only correct parse is:

	(a && b) *= c;                  (3)

which is semantically meaningless.  PCC interprets it as (2), due to
a bug in yacc.  (PCC uses a yacc parser, if you didn't know.)  Yacc is
unlikely to be fixed, since it is a fairly obscure implementation of the
LALR parser generation algorithm which is itself pretty confusing.

John Levine, decvax!yale-co!jrl, ucbvax!cbosgd!ima!johnl,
{research|alice|rabbit|floyd|amd70}!ima!johnl

tjt (04/01/83)

Some of this depends on what you would like '&&' to mean as well as
how you would like assignment to behave (note the key phrase "would
like").  One possibility is for:
			a && b
to be equivalent to:
			a ? a : b
Without a re-evaluation of a. i.e. another of C syntactic devices to
trick the programmer into doing most of the optimizing.

Then the question becomes whether the statement
		a ? a : b *= c;
should make any sense.  It could, if you distribute the expression
through the conditional, and make it equivalent to:
		if (a) a *= c; else b *= c;

In the C reference manual:
			a && b
is defined as equivalent to (although not in so many words):
			a ? 1 : ( b ? 1 : 0 )
In addition, the '?' operator does yield a lvalue, but there's always
"what if ...".

grahamr (04/04/83)

I, too, want this argument to end, but without any mud slung at yacc.
With all due respect, there is no yacc bug.  We were all brought up on
appendix A of the yacc manual, where there is only one set of productions
for an "expression".  The C language is not this way; it has lvalues to
deal with AND THEY ARE *SYNTACTICALLY* DIFFERENT FROM SIMPLE EXPRESSIONS.

This is the fragment we are dealing with:

expr	:	expr ANDAND expr
	|	lvalue ASSIGN expr
	|	primary
	;

primary	:	ID
	;

lvalue	:	ID
	;

The input is "ID ANDAND ID ASSIGN ID".  Please note that the phrase
"ID ANDAND ID" cannot be reduced to "lvalue".  Look in the C Reference
Manual and you will find that the same is true there.  This means that
the parser simply will not do this reduction.  This characteristic of
LR parsers is supposed to be a feature.  Precedence rules are invoked
when there are two or more legal parses.  That is not happening here and
therefore the precedence rules are not being invoked.

On the subject of cdecl:  We are working on the problem.  If you don't
have it by 4/8, send me mail or give me a call and I'll put you on my
bulk mailing list.

	Graham Ross
	Tektronix, Inc.
	(ucbvax|decvax)!teklabs!tekmdp!grahamr
	(503) 629-1953

crc (04/06/83)

Sorry John,
	(a && b) is not an Lvalue and therefore can never be the
address of the result of an assignment. Try reading "The C Programming
Language". An asignment must store the result somewhere, so the left
side of the assignment must supply an address; ( a && b) is logical expression,
True or Not True, not an address.