[gnu.gcc.bug] GCC 1.30 complaints

dsgn047@UCSCI.UCSC.EDU (10017047) (10/22/88)

Most of these aren't really bugs, but I think they should be reported
anyway.

1)  The infamous prototyping bug (you know, the one where you prototype a
function, and then declare it old-style?):  I will, for the moment, accept
rms' reasons why it does this, but only until I have enough time to hack
the code a bit.  Microsoft C (gack, I know) does *not* have this problem,
and I'm somewhat curious why (I'll look into it), and I'm sure all the
people who program (or have access to) GCC can certainly outprogram the
people at Microsoft 8-).

2)  Loop optimization.  GCC 1.30 does *not* get rid of empty for loops;
does anybody know why? (I.e., 'for (a=0;a<100;a++);' is executed in its
entirety.)

3)  Optimization with floating-point numbers.  I did a little 'max' routine,
returning the greater of two floating point numbers, and then caused GCC to
inline it.  When I called 'max(1.2,3.4),' it actually did the compare.
If I changed the floating-point numbers to integers (and changed the test
numbers accordingly), it *knew* which of the larger were.  Why the
inconsistency?  This is, of course, on GCC 1.30, on a VAX running 4.3.

So that I don't sound snotty, I am, of course, very impressed with GCC, and
most/all of these were found when I was comparing GCC to MS C running under
XENIX(tm) (MSC 4.5ish for the '386, 5.1 for the '286), and GCC does win in
some circumstances (MSC cannot inline, and boy is that nice at times).

Sean.
--------------------
Sean Eric Fagan
seanf@sco[.COM?]
or (temporarily) dsgn047@ucsci.ucsc.edu
"Batch jobs?  We don' need no steenkin' batch jobs!"

ekrell@hector.UUCP (Eduardo Krell) (10/22/88)

In article <8810220131.AA00312@ucsci.ucsc.edu> dsgn047@UCSCI.UCSC.EDU (10017047) writes:

>2)  Loop optimization.  GCC 1.30 does *not* get rid of empty for loops;
>does anybody know why? (I.e., 'for (a=0;a<100;a++);' is executed in its
>entirety.)

I don't know what your C compiler does, but if a is not equal to 100
after this for loop, it's generating wrong code.
You can't throw away this for loop since it is modifying a variable in
an outer scope.
    
Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ

UUCP: {att,decvax,ucbvax}!ulysses!ekrell  Internet: ekrell@ulysses.att.com

bader+@ANDREW.CMU.EDU (Miles Bader) (10/23/88)

ulysses!hector!ekrell@tut.cis.ohio-state.edu  (Eduardo Krell) writes:
> I don't know what your C compiler does, but if a is not equal to 100
> after this for loop, it's generating wrong code.
> You can't throw away this for loop since it is modifying a variable in
> an outer scope.

a=100; /* look ma, no loop! */

ekrell@hector.UUCP (Eduardo Krell) (10/23/88)

In article <QXMAg1y00Uka8BXnMW@andrew.cmu.edu> bader+@ANDREW.CMU.EDU (Miles Bader) writes:

>a=100; /* look ma, no loop! */

Great. Now, what about

	for(a=1;a<=100;a=foo(a));

Where foo is a function defined elsewhere.
    
Eduardo Krell                   AT&T Bell Laboratories, Murray Hill, NJ

UUCP: {att,decvax,ucbvax}!ulysses!ekrell  Internet: ekrell@ulysses.att.com

ron@vaxnix.tandy.COM (Ron Light) (10/23/88)

In article <8810220131.AA00312@ucsci.ucsc.edu>,
dsgn047@UCSCI.UCSC.EDU (10017047) writes:
> 2)  Loop optimization.  GCC 1.30 does *not* get rid of empty for loops;
> does anybody know why? (I.e., 'for (a=0;a<100;a++);' is executed in its
> entirety.)

I would find it sheer lunacy to have that loop eliminated in favor of a=100.
That type of loop is used QUIET often for DELAY loops.  Try writing a driver
sometime where you need a delay loop, and see what happens when "a=100" is
all that's generated with no delay.

james@bigtex.cactus.org (James Van Artsdalen) (10/24/88)

In <1531@vaxnix.tandy.COM>, ron@vaxnix.tandy.COM (Ron Light) wrote:

> I would find it sheer lunacy to have that loop eliminated in favor of
> a=100.  That type of loop is used QUITE often for DELAY loops.  Try
> writing a driver sometime where you need a delay loop, and see what
> happens when "a=100" is all that's generated with no delay.

Surely you don't seriously expect that kind of loop to work?  Good
Lord, even if you figure out the right constants for a particular
compiler on a particular machine, what happens when Tandy builds a
33MHz 386, or GNU C v2.0 generates code twice as good as v1.30, or you
switch to some other compiler or CPU altogether?
-- 
James R. Van Artsdalen      james@bigtex.cactus.org      "Live Free or Die"
Home: 512-346-2444 Work: 338-8789       9505 Arboretum Blvd Austin TX 78759

bader+@ANDREW.CMU.EDU (Miles Bader) (10/24/88)

ulysses!hector!ekrell@tut.cis.ohio-state.edu  (Eduardo Krell) writes:
> bader+@ANDREW.CMU.EDU (Miles Bader) writes:
> 
> >a=100; /* look ma, no loop! */
> 
> Great. Now, what about
> 
>         for(a=1;a<=100;a=foo(a));
> 
> Where foo is a function defined elsewhere.

Then you generate the loop.  It's not nearly the same case.

-Miles

ron@vaxnix.tandy.COM (Ron Light) (10/25/88)

In article <9773@bigtex.cactus.org> james@bigtex.cactus.org (James Van Artsdalen) writes:
>Surely you don't seriously expect that kind of loop to work?  Good
>Lord, even if you figure out the right constants for a particular
>compiler on a particular machine, what happens when Tandy builds a
>33MHz 386, or GNU C v2.0 generates code twice as good as v1.30, or you
>switch to some other compiler or CPU altogether?


Your point is well taken, John, and I would never use such a loop for
anything that was even close to timing critical or important.  But my
discussion was for the purpose of an example of why a loop is sometimes
necessary.  If I have a delay loop, for whatever reason, I would be very
angry if the compiler decided, for itself, "Oh, this is stupid, we don't
need this."  A compiler's job is not to make higher level decisions on what
it thinks I want, or do not want.  It's job is to take the source code I've
given it and try to produce the most reasonable approximation of assembly
or binary code.  In the original example given, I find that a=100 is about
as far away from what was intended as one can possibly get.

jbs@fenchurch.MIT.EDU (Jeff Siegal) (10/27/88)

In article <1608@vaxnix.tandy.COM> ron@vaxnix.UUCP (Ron Light) writes:
>In article <9773@bigtex.cactus.org> james@bigtex.cactus.org (James Van Artsdalen) writes:
>If I have a delay loop, for whatever reason, I would be very
>angry if the compiler decided, for itself, "Oh, this is stupid, we don't
>need this."

The compiler doesn't know it is a "delay loop."  It only knows that it
is an empty loop.  It might have resulted from code like:

	for (i=0; i<100; ++i) {
	    assert(a[i] != 0);
	}

when compiled with NDEBUG=1

>A compiler's job is [...]to take the source code I've
>given it and try to produce the most reasonable approximation of assembly
>or binary code.

Perhaps, but the job of an *optimizing*compiler* is to produce the
fastest/smallest code sequence it can, out of the set of possible code
sequences which perform the same function.

Jeff Siegal

james@bigtex.cactus.org (James Van Artsdalen) (10/27/88)

In <10343@eddie.MIT.EDU>, jbs@fenchurch.MIT.EDU (Jeff Siegal) wrote:

> In article <1608@vaxnix.tandy.COM> ron@vaxnix.UUCP (Ron Light) writes:
> >In article <9773@bigtex.cactus.org> james@bigtex.cactus.org (James Van Artsdalen) writes:
> >If I have a delay loop, for whatever reason, I would be very
> >angry if the compiler decided, for itself, "Oh, this is stupid, we don't
> >need this."

*PLEASE* be more careful with attributions.  I did not write the text
above.  I do write device driver code professionally, and I do *not*
want anyone (especially my boss) to think I might have produced such a
comment.
-- 
James R. Van Artsdalen      james@bigtex.cactus.org      "Live Free or Die"
Home: 512-346-2444 Work: 338-8789       9505 Arboretum Blvd Austin TX 78759

paul@UUNET.UU.NET (Paul Hudson) (10/27/88)

I've been reading all this stuff about whether or not loops should be
removed with some incredulity, so here's my tuppence worth.

All I require from a compiler is that it produces the output and processes the
input in the manner specified by the semantics of my program.

So, if the compiler notices that removing a loop doesn't alter the
semantics, that's fine by me. I haven't noticed anyone complaining that
gcc puts things in registers without a register declaration, or the myriad of
other changes an optimising compiler can do. Indeed these semantics-preserving
transforms are what makes an optimising compiler optimising!

The problem of what can or cannot been done is a much studied subject - 
see, for example the Dragon book.

Anything to do with timings is an entirely different ball game. The C
standard has nothing to say on this subject (correctly, in my view). You
shouldn't rely on a compiler's interpretation of code to ensure timing
constraints are met.

The effect of a program on store can be ensured by judicious use of volatile -
it's not just there for asynchronously changing locations. If you really want
the much discusssed empty loop to take some (still rather indeterminate) time,
declare "a" volatile.

There was a cryptic (to me, anyway) message concerning the loop
	"for (a=0; a < 100; a ++) a = foo(a);"

What to do here is clear - in general the compiler does not know what
"foo" can do in the way of side-effects, and has to compile the loop
as written.

I hope this has cleared some of the confusion (but alas, it's probably
added to it).

Paul Hudson

Snail mail: Monotype ADG	Email:	...!ukc!acorn!moncam!paul
	    Science Park,		paul@moncam.co.uk
	    Milton Road,	"Sun Microsysytems:
	    Cambridge,		 The Company is Arrogant (TM)"
	    CB4 4FQ