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