[comp.lang.c] Problem with #define'd macro...

c145gmk@utarlg.uta.edu (GORDON KEEGAN) (03/20/91)

Attempting to compile the following (fragment, but displays the problem)
results in an 'invalid target for assignment' error on our VAX running
VMS 5.3-1, using VAX C 3.1-051.  It compiles fine if I remove the division
and multiplication.  Any insight posted or e-mailed would be greatly
appreciated.  (e-mail will be summarized...)


-----------------------  begin code fragment  -----------------------
#define DIV_MOD(d,r,x,y) ( y == 0.0 ? d = 0.0, r = x : d = x/y, r = x - d*y )

main()
{
float a,b;
float remainder;
float quotient;

a = 5, b = 2; DIV_MOD(quotient,remainder,a,b);
printf("DIV_MOD(%f,%f,%f,%f)\n", quotient, remainder, a, b);
}
-----------------------  end code fragment  -------------------------

aTdHvAaNnKcSe

-----------------------------------------------------------------------------
|  Gordon Keegan                    ||   Bitnet  : c145gmk@utarlg           |
|  Systems Programmer               ||   THEnet  : UTARLG::C145GMK          |
|  Academic Computing Services      ||   Internet: c145gmk@utarlg.uta.edu   |
|  University of Texas, Arlington   ||   AT&TNet : 817-273-2208             |
-----------------------------------------------------------------------------

ravim@gtenmc.UUCP (Vox Populi) (03/29/91)

In article <1991Mar20.150301.9941@evax.arl.utexas.edu> c145gmk@utarlg.uta.edu writes:
>Attempting to compile the following (fragment, but displays the problem)
>results in an 'invalid target for assignment' error on our VAX running

>
>#define DIV_MOD(d,r,x,y) ( y == 0.0 ? d = 0.0, r = x : d = x/y, r = x - d*y )

>a = 5, b = 2; DIV_MOD(quotient,remainder,a,b);

I think the compiler error that you were getting is because, operator
precedence is not observed here correctly.

According to K&R precedence table, operator ',' has lower precedence (in fact,
least precedence) than the tertiary operator '? :'. 
Hence you would need to raise the precedence of ',' operators in the
operands of '? :' in the macro defined above.

Hence, the correct definition would be
#define DIV_MOD(d,r,x,y) ( y == 0.0 ? (d = 0.0, r = x) : (d = x/y, r = x - d*y))

	-	Ravi Mandava

-- 
**********************   #include <stddisclaimer.h>  **************************
Ravi Mandava			e-mail :	ravim@gtenmc.gtetele.com
					  or    ravim@gtenmc.UUCP
*******************************************************************************

steve@groucho.ucar.edu (Steve Emmerson) (04/02/91)

In <1099@gtenmc.UUCP> ravim@gtenmc.UUCP (Vox Populi) writes:

>In article <1991Mar20.150301.9941@evax.arl.utexas.edu> c145gmk@utarlg.uta.edu
writes:
>>Attempting to compile the following (fragment, but displays the problem)
>>results in an 'invalid target for assignment' error on our VAX running

>>#define DIV_MOD(d,r,x,y) ( y == 0.0 ? d = 0.0, r = x : d = x/y, r = x - d*y )

>>a = 5, b = 2; DIV_MOD(quotient,remainder,a,b);

>I think the compiler error that you were getting is because, operator
>precedence is not observed here correctly.

I believe the above statement is false because 

	1) the string in question (which is an expression):

		a == b ? c=d, e=f : g=h, i=j

	   can be generated from the K&R1 grammar; and

	2) precedence is irrelevant in determining whether or not a string
	   is valid.

The expression-string can be generated from the following sequence of 
production rules (Appendix A, K&R1):

    exp ? exp : exp
    exp binop exp ? exp , exp : exp , exp
    primary == primary ? lvalue asgnop exp , lvalue asgnop exp : 
	                 lvalue asgnop exp , lvalue asgnop exp
    identifier == identifier ? identifier = primary, identifier = primary :
			       identifier = primary, identifier = primary
    a == b ? c=identifier, e=identifier :
	     g=identifier, i=identifier
    a == b ? c=d, e=f : g=h, i=j

Precedence, on the other hand, is a tool used by parsers to
disambiguate between two or more ways of generating the same string
from a given grammar.  The validity of a given string, however, is
determined solely on the basis of whether or not it can be generated by
the production rules of the grammar.  Since the above string can, then
it's valid under the K&R1 grammar.

This might seem counter intuitive and, indeed, Standard C has closed
this `loophole' by redefining the production rules in such a manner
that the above string cannot be generated.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

volpe@camelback.crd.ge.com (Christopher R Volpe) (04/02/91)

In article <10868@ncar.ucar.edu>, steve@groucho.ucar.edu (Steve
Emmerson) writes:
|>In <1099@gtenmc.UUCP> ravim@gtenmc.UUCP (Vox Populi) writes:
|>
|>>In article <1991Mar20.150301.9941@evax.arl.utexas.edu>
c145gmk@utarlg.uta.edu
|>writes:
|>>>Attempting to compile the following (fragment, but displays the problem)
|>>>results in an 'invalid target for assignment' error on our VAX running
|>
|>>>#define DIV_MOD(d,r,x,y) ( y == 0.0 ? d = 0.0, r = x : d = x/y, r =
x - d*y )
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                          This is the root of the
                              precedence problem because the value "x/y" is
                              being assigned to the result of the conditional
                              operator, which is not an lvalue, and therefore
                              an illegal target for assignment. 
|>
|>>>a = 5, b = 2; DIV_MOD(quotient,remainder,a,b);
|>
|>>I think the compiler error that you were getting is because, operator
|>>precedence is not observed here correctly.
|>
|>I believe the above statement is false because 
|>
|>	1) the string in question (which is an expression):
|>
|>		a == b ? c=d, e=f : g=h, i=j
|>
|>	   can be generated from the K&R1 grammar; and

Compilers complain about plenty of other things besides strings not being
generated from the grammar. Ever hear of undeclared variables?

|>
|>	2) precedence is irrelevant in determining whether or not a string
|>	   is valid.
           
The compiler didn't punt with a parse error, did it? It parsed it
the "wrong" way of the two possible ways (given the grammar and ingoring
the precedence rules.) By "wrong" I mean in terms of what the programmer
wanted. It was right according to the precedence rules. The problem was
not that the syntax was violated, but rather that, because of the
precedence rules, an assignment was made to a non-lvalue.

|>Precedence, on the other hand, is a tool used by parsers to
|>disambiguate between two or more ways of generating the same string
|>from a given grammar.  The validity of a given string, however, is
|>determined solely on the basis of whether or not it can be generated by
|>the production rules of the grammar. 

Compilers do not compile by syntax alone. The grammar is not a complete
definition of the language.

==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

volpe@camelback.crd.ge.com (Christopher R Volpe) (04/04/91)

In article <18146@crdgw1.crd.ge.com>, volpe@camelback.crd.ge.com
(Christopher R Volpe) writes:
|>In article <10868@ncar.ucar.edu>, steve@groucho.ucar.edu (Steve
|>Emmerson) writes:
|>|>In <1099@gtenmc.UUCP> ravim@gtenmc.UUCP (Vox Populi) writes:
|>|>
|>|>>In article <1991Mar20.150301.9941@evax.arl.utexas.edu>
|>c145gmk@utarlg.uta.edu
|>|>writes:
|>|>>>Attempting to compile the following (fragment, but displays the problem)
|>|>>>results in an 'invalid target for assignment' error on our VAX running
|>|>
|>|>>>#define DIV_MOD(d,r,x,y) ( y == 0.0 ? d = 0.0, r = x : d = x/y, r =
|>x - d*y )
|>                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|>                                          This is the root of the
|>                              precedence problem because the value "x/y" is
|>                              being assigned to the result of the conditional
|>                              operator, which is not an lvalue, and therefore
|>                              an illegal target for assignment. 

Steve Emmerson pointed out to me that the above expression is
perfectly legal because the grammar in both K&R1 and K&R2  prevent
parsing the ?: operator as the lhs of the assignment, thus precedence
doesn't apply. (I put too much faith in Table 2.1). BTW, both
GCC and SunOS cc get this completely wrong. They complain about invalid lhs
of assignment.

Thanks, Steve.

-Chris
                                                           
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

steve@groucho.ucar.edu (Steve Emmerson) (04/04/91)

In <18200@crdgw1.crd.ge.com> volpe@camelback.crd.ge.com (Christopher R Volpe) 
writes:

>|>|>>>#define DIV_MOD(d,r,x,y) ( y == 0.0 ? d = 0.0, r = x : d = x/y, r =
>|>x - d*y )
>|>                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>|>                                          This is the root of the
>|>                              precedence problem because the value "x/y" is
>|>                              being assigned to the result of the conditional
>|>                              operator, which is not an lvalue, and therefore
>|>                              an illegal target for assignment. 

>Steve Emmerson pointed out to me that the above expression is
>perfectly legal because the grammar in both K&R1 and K&R2  prevent
>parsing the ?: operator as the lhs of the assignment, thus precedence
>doesn't apply. (I put too much faith in Table 2.1). BTW, both
>GCC and SunOS cc get this completely wrong. They complain about invalid lhs
>of assignment.

Whoops!  Hang on a second!

I said the expression was valid according to the K&R1 grammar.  It is,
however, quite invalid under Standard C: it cannot be generated from
the grammar.

The original question was in the context of K&R1 C.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

volpe@camelback.crd.ge.com (Christopher R Volpe) (04/05/91)

In article <10903@ncar.ucar.edu>, steve@groucho.ucar.edu (Steve
Emmerson) writes:
|>Whoops!  Hang on a second!
|>
|>I said the expression was valid according to the K&R1 grammar.  It is,
|>however, quite invalid under Standard C: it cannot be generated from
|>the grammar.
|>
|>The original question was in the context of K&R1 C.

Ah, right. Sorry. Yes, it's valid under K&R1, and SunOS cc incorrectly
flags it. Gcc -traditional also does the same incorrect thing. 
The default gcc (i.e. ansi) correctly flags it, but for the wrong reason.
According to ANSI it's a pure syntax violation, but gcc reports
"invalid lvalue in assignment". But that's because the "then" branch
of the conditional isn't an lvalue. If we take advantage of GCC's
generalized lvalues, we get the following:

#include <stdio.h>
int main()
{
  int a=0,b=0,c=0;
  c=0;
/*
  This get's reported as invalid lhs of assignment
  c ? c = a : c = b ;
*/

/*
  This is a prefectly valid generalized lvalue
*/
  (c ? a : b) = 5;

/*
  This is a syntax error according to ANSI, but GCC treats it like the above
*/
  c ? a : b = 5;

}

GCC behaves the same way with -ansi. However, it produces the 
"invalid lhs" again when using -pedantic. It never finds the syntax
violation.

|>
|>Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve
                            
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com