[eunet.bugs.4bsd] Ultrix CC bug?

bl@infovax.UUCP (Bj|rn Larsson) (09/15/89)

Hello netters,

 yesterday I came upon a strange behaviour in Ultrix 'C'. The following
test program causes cc to complain about the left-hand side of the marked
expression.

	main()
	  {
	  short *p;
	  tst(p);
	  }

	tst (p)
	  short *p;
	  {
	  long	l;
	  l = *((long *) p)++;	/* <<< Here! */
	  }

  In my view,

	p			is a pointer to short,
	(long *) p		is a pointer to long,
	((long *) p)		is also a pointer to long,
	((long *) p)++		increments the above *long* pointer,
	*((long *) p)		is the long pointed to,

	thus

	*((long *) p)++		has the value of the *long* pointed
				to by p, and the *long* pointer is
				set to point to the next long (i.e.
				if sizeof (long)== 2*sizeof(short)
				then p will be incremented by two,
				counted in short's).

  Any objections? I could add that both Turbo C, MicroSoft C, and the
MicroTek C 68000 cross-compiler compile this as I believe 'correctly'.
And this is no problem, I fixed it at another place - but it's inte-
resting to hear what yous C compilers do...


							Bjorn

-- 
 ====================== InfoVox = Speech Technology =======================
 Bjorn Larsson, INFOVOX AB      :      ...seismo!mcvax!kth!sunic!infovax!bl
 Box 2503                       :         bl@infovox.se
 S-171 02 Solna, Sweden         :         Phone (+46) 8 735 80 90

maart@cs.vu.nl (Maarten Litmaath) (09/16/89)

bl@infovax.UUCP (Bj|rn Larsson) writes:
\...	*((long *) p)++		has the value of the *long* pointed
\				to by p, and the *long* pointer is
\				set to point to the next long (i.e.
\				if sizeof (long)== 2*sizeof(short)
\				then p will be incremented by two,
\				counted in short's).
\
\  Any objections? I could add that both Turbo C, MicroSoft C, and the
\MicroTek C 68000 cross-compiler compile this as I believe 'correctly'.

It seems all those compilers are wrong...!
Now where's that article I posted not too long ago to comp.lang.c?
Aha!  Here it is.
Allright.  A compiler that allows the abovementioned construct is wrong for
two reasons:

1)	It allows the `++' operator to be applied to an Rvalue expression;
	only Lvalue expressions may be operand of an increment operator, e.g.

		x++
		a[i]++

	This isn't so strange:

		x++
	
	is equivalent to

		x = x + 1

	which doesn't make sense for arbitrary (Rvalue) expressions.
2)	It increments the wrong variable; a cast is equivalent to an
	assignment to an invisible temporary variable (with the usual
	restrictions and conversions):

		foo	x;

		... (bar) x ...

	becomes

		foo	x;
		bar	cast_tmp;	/* `invisible' temp variable */

		... (cast_tmp = x) ...
	
	If we write the latter expression as

		(cast_tmp = x, cast_tmp)

	it's clearly `cast_tmp' which should be incremented (if a `++'
	operator is appended), were this possible at all; definitely NOT `x'.
-- 
   creat(2) shouldn't have been create(2): |Maarten Litmaath @ VU Amsterdam:
      it shouldn't have existed at all.    |maart@cs.vu.nl, mcvax!botter!maart