[comp.lang.c] Bug in Green Hills compiler

ok@quintus.UUCP (Richard A. O'Keefe) (12/19/87)

According to the UNIX System V Programmer's Guide, 1987
paperback edition, page 740:

	The expression E1[E2] is identical (by definition)
	to *((E1)+(E2)).

The October 86 draft of the ANSI C standard said (Rationale
section 3.3.2.1)
	The Committee found no reason to disallow the
	symmetry that permits a[i] to be written as i[a].
and in the standard proper
	The definition ... is that E1[E2] is identical
	to (*(E1+(E2))).
[The two definitions are equivalent.]

What we're getting at here is that if you want to represent
positions in 3D space, a good dodge is to write

#define x_of(V) 0[V]
#define y_of(V) 1[V]
#define z_of(V) 2[V]

Notice that there are no superfluous parentheses, that
this notation can be read directly as "2nd element of V",
and that this has always been explicitly legal in C.

Some versions of the Green Hills C compiler for MC680x0 do not
accept this syntax.  There may be other versions which do accept it.
There may be other compilers with this error:  the VAX-11 C manual
for VMS says "addr[intexp]" which suggests that it MAY have the
same mistake.

BTW: now that the ANSI C committee have decided to flout centuries
of mathematical tradition and make (X+Y) different from X+Y, what
does this do to E1[E2]?  [The two definitions above are NOT
equivalent if parentheses act as in FORTRAN.  This is a good
reason why parentheses should have their usual mathematical
meaning:  straightforward reasoning about a program can go
seriously wrong if parentheses act so strangely.]

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/20/87)

In article <482@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>BTW: now that the ANSI C committee have decided to flout centuries
>of mathematical tradition and make (X+Y) different from X+Y, what
>does this do to E1[E2]?

First of all, you appear to be under some misunderstanding.
(X+Y) is no more different from X+Y under the new rule than it ever was.
The only "flouting of mathematical tradition" is that done by the hardware,
which instead of working with abstract mathematical symbols uses imperfect
representations of numeric values.  Overflow and loss of precision were by
no means invented by X3J11; we just had to figure out how to cope with them.

The meaning of E1[E2] is unaffected by the new non-regrouping rule.
It is still equivalent to E2[E1].

It is certainly true, as you said, that straightforward reasoning about
a program can go seriously wrong, but not for the reason you stated.
The real problem is that, although program source notation resembles
mathematical notation, it is NOT the same thing and does NOT have the
same properties.  Assumptions to the contrary are what leads one astray.

There are methodologies for correct reasoning about programs; the names
Dijkstra and Hoare come to mind.

ok@quintus.UUCP (Richard A. O'Keefe) (12/21/87)

In article <6883@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <482@cresswell.quintus.UUCP> [I wrote]:
> >BTW: now that the ANSI C committee have decided to flout centuries
> >of mathematical tradition and make (X+Y) different from X+Y, what
> >does this do to E1[E2]?
> 
> First of all, you appear to be under some misunderstanding.
> (X+Y) is no more different from X+Y under the new rule than it ever was.

Under the new rules, (X+Y) and X+Y are in fact different, that is,
they BEHAVE differently.  (X and Y stand for arbitrary expressions.)
The point here is that E1[E2] has in the past been defined in one of
two previously equivalent ways:
	(*((E1)+(E2)))
or	(*(E1+(E2)))
If parentheses have an operational effect, these two definitions are
no longer equivalent.  What I was asking for, and still would like, is
a plain statement of what the new definition of E1[E2] is, and in
particular, a plain statement of under which conditions the compiler
is entitled to merge E1 and E2 rather than evaluating them separately.
(Note that this is POINTER arithmetic, >>not<< integer arithmetic, so
statements about equivalence if integer overflow is disabled are not
enough to tell me whether the compiler is entitled to treat
2[a+1] as a[3] or not.)  Surely this isn't too much to ask?

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/21/87)

In article <484@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>Under the new rules, (X+Y) and X+Y are in fact different, that is,
>they BEHAVE differently.

No, they don't, unless the expressions X and Y contain operators that
bind more tightly that + and "X+Y" is imbedded in a context where that
matters.

>The point here is that E1[E2] has in the past been defined in one of
>two previously equivalent ways:
>	(*((E1)+(E2)))
>or	(*(E1+(E2)))
>If parentheses have an operational effect, these two definitions are
>no longer equivalent.

Parentheses have the same effect they have always had in C, namely they
can be used to override default operator associativity and precedence.

The only change brought on by the latest X3J11 meeting is that compilers
are no longer free to run rampant when optimizing expressions involving
nominally commutative+associative operators.

>What I was asking for, and still would like, is
>a plain statement of what the new definition of E1[E2] is,

The first one you quoted is probably the best form to use, since E1 may
contain some operator that binds more weakly than +.

>statements about equivalence if integer overflow is disabled are not
>enough to tell me whether the compiler is entitled to treat
>2[a+1] as a[3] or not.

2[a+1] is equivalent to *(2+(a+1)).  Assuming that a through a+3 are all
meaningful addresses, then this is indeed equivalent to a[3].