🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.programmer
Article #3660

Re: gcc -O2 bug

#3660
From: Dan Pop
Date: Thu, 08 Aug 1996 00:00
103 lines
4237 bytes
In <4ubnat$75u@freeside.fc.net> mrbig@freeside.fc.net (Mike Big) writes:

>/* 
>I'v found what I think might be a bug in gcc's optimization.  The

The bug is right into _your_ code.

>code below works corectly when compiled using "gcc -Wall -O1"
>but fails when compiled using "gcc -Wall -O2".  I'v tried it using
>both gcc 2.7.2 & 2.6.3 on Linux 1.3.100, Linux 2.0.10, & SunOS 4.1.3
>w/ the same result.  The problem is that eventhough flag gets set to 
>0, the while loop does NOT exit.  Also, when you uncomment the printf 
>inside the loop, all is well again even w/ the -O2 optimizations.  
>Any ideas are welcome.  (This is my first time using signals, so 
>maybe something is wrong there but I still think the -O2 should not 
>change things.)
>
>*/
>
>#include <stdio.h>
>#include <sys/time.h>
>#include <sys/types.h>
>#include <signal.h>
>
>void fca(); /* SIGALRM handler function */
>
>long counter;
>int *flag_pt;
>
>int main()
>{
>  struct itimerval timer_length;
>  int  flag;
>  
>  flag_pt=&flag;
>  /* specify signal handler */
>  signal(SIGALRM, fca);
>
>  /* set the signal to repeat every 3 seconds */
>  timer_length.it_value.tv_sec=3;     /* initial time */
>  timer_length.it_value.tv_usec=0;
>  timer_length.it_interval.tv_sec=3;  /* repeat */
>  timer_length.it_interval.tv_usec=0;
>  setitimer(ITIMER_REAL, &timer_length, NULL);
>  
>  flag=time(NULL); /* this is so that the compiler won't substitute a constant
>                      for flag as it might if I did something like flag=1; */
>
>  /* count until interrupted (after 3 seconds) */
>  counter=0;
>  while(flag){ /* does NOT exit when using gcc -O2 */

The compiler "sees" that flag is a loop invariant and optimizes the
test: if flag is non-zero, the loop becomes an infinite loop, otherwise
the loop is skipped.  This is a perfectly legal optimization.  It is YOUR
responsibility to declare flag with the volatile qualifier, to inform
the compiler that its value might change behind its back and disable
the undesired optimization.

>    counter++;
>    /* uncomenting the printf below will fix things. weird heh */

There is nothing weird here.  flag is accessible via a global pointer 
so printf might change its value, as a side effect.  The compiler can't
tell whether this will happen or not, so it cannot assume that flag is
a loop invariant in the presence of a function call inside the loop.
The above-mentioned optimization is illegal now.  A smarter compiler
might have more information about printf and decide from its invocation
that it cannot modify flag and still do the optimization :-)

>    /* printf("counter=%ld flag=%d\n",counter,flag); */ 
>  }
>
>  exit(0);

I can't see any declaration in scope for exit(), and it is NOT a function
returning int.  Your code invokes undefined behaviour.

>}
>
>void fca()

Bad declaration for a signal handler.  It should have one argument of type
int.

>{
>  printf("counter=%ld\n",counter);
>  printf("before flag=%d\n",*flag_pt);
>  *flag_pt=0;
>  printf("after  flag=%d\n",*flag_pt);
>}

You're not allowed to call printf inside a signal handler, especially
when you have library function calls in the code which might be
interrupted when the handler is invoked.

Dan
--
Dan Pop
CERN, CN Division
Email: Dan.Pop@cern.ch 
Mail:  CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Technical Details
Message-ID: <danpop.839504721@news.cern.ch>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail
References: <4ubnat$75u@freeside.fc.net>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 11318c,7d30cae02ba9b089
X-Google-Attributes: gid11318c,public
X-Google-Thread: 10c696,7d30cae02ba9b089
X-Google-Attributes: gid10c696,public
X-Google-Thread: fc89c,7d30cae02ba9b089
X-Google-Attributes: gidfc89c,public
X-Google-Thread: 1014db,7d30cae02ba9b089
X-Google-Attributes: gid1014db,public
From: Dan.Pop@cern.ch (Dan Pop)
Subject: Re: gcc -O2 bug
Date: 1996/08/08
Message-ID: <danpop.839504721@news.cern.ch>
X-Deja-AN: 172899012
sender: news@news.cern.ch (USENET News System)
x-nntp-posting-host: ues5.cern.ch
references: <4ubnat$75u@freeside.fc.net>
organization: CERN European Lab for Particle Physics
keywords: gcc bug O2
newsgroups: comp.unix.programmer,gnu.gcc.help,comp.os.linux.development.apps,comp.lang.c