[comp.lang.c] Lvalues and casts

net@tub.UUCP (Oliver Laumann) (05/23/89)

I just found out (by accident; I didn't want to actually use it)
that the GNU cc with the -ansi option, the cc under SunOS 4.0 and
the Greenhills C-compiler all happily compile the following program
(without any warnings):

    f () {
	int *ip;
	char *cp;

	(int *)cp = ip;
    }

The PCC, however, says "illegal lvalue in assignment".  Is this legal
C, i.e. is the result of a cast really an lvalue?

Regards,
--
Oliver Laumann              net@TUB.BITNET              net@tub.UUCP

blarson@skat.usc.edu (Bob Larson) (05/24/89)

In article <847@tub.UUCP> net@tub.UUCP (Oliver Laumann) writes:
>	(int *)cp = ip;

>The PCC, however, says "illegal lvalue in assignment".  Is this legal
>C, i.e. is the result of a cast really an lvalue?

Casts are never lvalues.

Gcc documents this bug as a feature.  (Hopefully it is caught
by -pedantic)
-- 
Bob Larson	Arpa:	blarson@skat.usc.edu
Uucp: {uunet,cit-vax}!usc!skat!blarson
Prime mailing list:	info-prime-request%ais1@ecla.usc.edu
			usc!ais1!info-prime-request

ka@june.cs.washington.edu (Kenneth Almquist) (05/24/89)

net@tub.UUCP (Oliver Laumann) asks:

> 	(int *)cp = ip;
>
> Is this legal C, i.e. is the result of a cast really an lvalue?

No.

On most machines, converting from a character pointer to an integer
pointer does not generate any executable code, so the cast can be
discarded early on.  If the compiler tests for valid lvalues after it
discards casts which don't generate code, it will fail to detect that
the left hand side of the assignment is not an lvalue.

In the case of gcc, the fact that the results of a cast can be used
as an lvalue is a feature rather than a bug.  This feature can be
disabled by compiling with the -pedantic option.
				Kenneth Almquist

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/24/89)

In article <847@tub.UUCP> net@tub.UUCP (Oliver Laumann) writes:
>	(int *)cp = ip;
>The PCC, however, says "illegal lvalue in assignment".  Is this legal
>C, i.e. is the result of a cast really an lvalue?

No, to the contrary it is not, and that is what the compiler is trying
to tell you in its obscure way.  The target of an assignment is required
to be a modifiable lvalue.

chris@mimsy.UUCP (Chris Torek) (05/24/89)

In article <847@tub.UUCP> net@tub.UUCP (Oliver Laumann) writes:
-I just found out (by accident; I didn't want to actually use it)
-that the GNU cc with the -ansi option, the cc under SunOS 4.0 and
-the Greenhills C-compiler all happily compile the following program
-(without any warnings):
-
-    f () {
-	int *ip;
-	char *cp;
-
-	(int *)cp = ip;
-    }
-
-The PCC, however, says "illegal lvalue in assignment".  Is this legal
-C, i.e. is the result of a cast really an lvalue?

The result of a cast is not an lvalue (is an rvalue).  GCC accepts it
as an extension; the Greenhills compiler probably accepts it because
some versions of PCC did; correct PCCs reject it.

If you compile with

	gcc -ansi -pedantic

GCC does reject the assignment.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

henry@utzoo.uucp (Henry Spencer) (05/24/89)

In article <847@tub.UUCP> net@tub.UUCP (Oliver Laumann) writes:
>	(int *)cp = ip;
>
>The PCC, however, says "illegal lvalue in assignment".  Is this legal
>C, i.e. is the result of a cast really an lvalue?

No.  Many compilers have accepted it, historically, but it has never
been legal C and it is not legal ANSI C.
-- 
Van Allen, adj: pertaining to  |     Henry Spencer at U of Toronto Zoology
deadly hazards to spaceflight. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

diamond@diamond.csl.sony.junet (Norman Diamond) (05/24/89)

In article <847@tub.UUCP> net@tub.UUCP (Oliver Laumann) writes:

>>	(int *)cp = ip;
>>The PCC, however, says "illegal lvalue in assignment".  Is this legal
>>C, i.e. is the result of a cast really an lvalue?

In article <17370@usc.edu> blarson@skat.usc.edu (Bob Larson) writes:

>Casts are never lvalues.

True.

>Gcc documents this bug as a feature.

Hmm.  There are ways that it could be construed as a feature, and it
doesn't break good code, but it really deserves a warning except when
some fool disables such a warning.

>(Hopefully it is caught by -pedantic)

Yeah, let's hope so.

Now get this:  I am trying to fix a PCC.  This PCC not only accepts
such a construct, but its own code USES such a construct.  And to
stop using it would require just enough of a change, non-minimal and
not necessary at this time, that I'm not fixing it at this time....

--
Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net)
  The above opinions are my own.   |  Why are programmers criticized for
  If they're also your opinions,   |  re-implementing the wheel, when car
  you're infringing my copyright.  |  manufacturers are praised for it?

randolph@ektools.UUCP (Gary L. Randolph) (05/25/89)

In article <1989May23.225818.9602@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <847@tub.UUCP> net@tub.UUCP (Oliver Laumann) writes:
>>	(int *)cp = ip;
>>
>>The PCC, however, says "illegal lvalue in assignment".  Is this legal
>>C, i.e. is the result of a cast really an lvalue?
>
>No.  Many compilers have accepted it, historically, but it has never
>been legal C and it is not legal ANSI C.

It is my understanding that all of the answers (similar to this one)
are correct, but I have an extension to the original question.  I have
used casts on the LHS of assignment, but without actually assigning to 
the cast.  Example:

func(data, semaphore)
char* data;
char semaphore;
{
if (semaphore=='a')
    *(int *)data = 22;
else if (semaphore=='b')
    *(float *)data = 64;
    .
    .
    .
}

Now the user of func() has supplied a pointer to some type, not 
necessarily a char. semaphore is used to determine the type of 
pointer func() actually received.  The location pointed to by
data is then modified as it is a legal lvalue.  I believe this to
be a typical use of the abused generic pointer, char*.  I would,
of course, use void* if I were using a dpANSI compiler.  It is my
understanding that using casts on the LHS of assignment in this
way is fully portable.  Right???

                         Gary  

chris@mimsy.UUCP (Chris Torek) (05/25/89)

In article <1912@ektools.UUCP> randolph@ektools.UUCP (Gary L. Randolph)
writes:
>... I have an extension to the original question.  I have
>used casts on the LHS of assignment, but without actually assigning to 
>the cast.  Example:
 ...
>if (semaphore=='a')
>    *(int *)data = 22;
>else if (semaphore=='b')
>    *(float *)data = 64;

The result of a cast is not an lvalue, but the result of an indirection
*is* an lvalue.  These assignments are thus to lvalues and hence legal
(provided, of course, the pointers point at the right objects).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris