🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.programmer
Article #3670

Re: gcc -O2 bug

#3670
From: Heinz Guenter Scharf
Date: Thu, 08 Aug 1996 00:00
78 lines
3522 bytes
Mike Big (mrbig@freeside.fc.net) wrote:
: /* 
: I'v found what I think might be a bug in gcc's optimization.  The
: 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.)

: Thanx in advance,
: Mike
: */

: #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 */
:     counter++;
:     /* uncomenting the printf below will fix things. weird heh */
:     /* printf("counter=%ld flag=%d\n",counter,flag); */ 
:   }

:   exit(0);
: }

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


I have had a look at the assembler output of the optimized and the unoptimized
compiler run. The optimization puts the flag into a register and tests if it is
zero, the non optimized versions look into the stackmemory, so if the signal-
routine changes the contents of the memory, the optimized version doesn't
notify anything. The calling of an external function forces the compiler to
reload the contents of the flag because the compiler cannot assume, that the
register sare all saved. A solution could be to create a sourcefile with a dummy
function with a parameter, or to disable temporarely the optimization.

-- 
If a listener nods his head when you're explaining your program, wake him up.
Technical Details
Message-ID: <4udk0p$3li@castle.dinoco.de>
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: guenter@castle.dinoco.de (Heinz Guenter Scharf)
Subject: Re: gcc -O2 bug
Date: 1996/08/08
Message-ID: <4udk0p$3li@castle.dinoco.de>
X-Deja-AN: 173066184
references: <4ubnat$75u@freeside.fc.net>
followup-to: comp.unix.programmer,gnu.gcc.help,comp.os.linux.development.apps,comp.lang.c
organization: Irgendwo im Rheinland...
newsgroups: comp.unix.programmer,gnu.gcc.help,comp.os.linux.development.apps,comp.lang.c