🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.programmer
Article #3659

Re: gcc -O2 bug

#3659
From: Thomas Wolf
Date: Thu, 08 Aug 1996 00:00
136 lines
6073 bytes
In article <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
:> 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);
:> }

The error you describe is not due to the compiler: it's in your
program. There are several problems with your code (ignoring all
the system dependencies with timers etc.).

1. Take a look at the prototype of 'signal'. It's equivalent to the
   following: 

      typedef void (*Signal_Handler) (int);
   
      Signal_Handler signal (int sig, Signal_Handler func);
   
   (I took apart the definition given in the standard in order to
   clarify things.)
   
   As you can see, a signal handler must be a function that takes one
   'int' argument and returns 'void'. Your 'fca' function should there-
   fore be declared as
   
      void fca (int sig);
   
2. A signal handler is only allowed to do a few things. The standard
   says:

   [ISO/IEC 9899:1990(E), 7.7.1.1]
   "... the behavior is undefined if the signal handler calls any
   function in the standard library other than the 'signal' function
   itself (with a first argument of the signal corresponding to the
   signal that caused the invocation of the handler) or refers to any
   object with static storage duration other than by assigning a value
   to a static duration variable of type 'volatile sig_atomic_t'".
   
   In particular, this means that you may not call 'printf' in your
   signal handler.
   
   It also tells you that static data that you access from within a
   signal handler must have type 'volatile sig_atomic_t'. Your 'flag_pt'
   has type 'int *', and so your signal handler is not allowed to access
   it.
   
3. Your problem occurred because you didn't tell the compiler that
   'flag' can be modified in ways unbeknownst to the compiler. If you
   had declared 'flag' as 'volatile int', the program might have worked
   despite points (1) and (2). The 'volatile' qualifier basically tells
   the copmpiler that it must not optimize away accesses to a variable.
   But note: even if it works when you add 'volatile', the program still
   invokes undefined behavior due to points (1) and (2), and you should
   correct it.
   
4. Your problem disappeared when you uncommented the 'printf' in the
   loop because the compiler could not be sure that 'printf' didn't
   modify 'flag' through an access through 'flag_pt', and thus it
   couldn't optimize away the test on 'flag' in the loop condition.
   
5. How your compiler determined that 'time' does not return something
   that results in 'flag' == 0 is a mystery to me. Maybe it didn't and
   this is just its version of undefined behavior?
   
6. '-O2' may well change things since it tells the compiler to use more
   optimizations than with '-O1'. With '-O1', it apparently didn't try
   to optimize the loop, with '-O2', it did.
   
Best regards,

  Thomas
----------------------------------------------------------------------
Swiss Federal Institute of Technology | Thomas Wolf
Software Engineering Laboratory       | EPFL-DI-LGL
Thomas Wolf (TW)                      | CH-1015 Lausanne (Suisse)
E-Mail: wolf@di.epfl.ch               | Phone: (++41 21)693 42 37
---------------------------------------------------------------------- 
Technical Details
Message-ID: <3209b0dc.0@epflnews.epfl.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: 1014db,7d30cae02ba9b089
X-Google-Attributes: gid1014db,public
X-Google-Thread: fc89c,7d30cae02ba9b089
X-Google-Attributes: gidfc89c,public
From: Thomas.Wolf@di.epfl.ch (Thomas Wolf)
Subject: Re: gcc -O2 bug
Date: 1996/08/08
Message-ID: <3209b0dc.0@epflnews.epfl.ch>
X-Deja-AN: 172889569
sender: wolf@lglsun6.epfl.ch (Thomas Wolf)
references: <4ubnat$75u@freeside.fc.net>
organization: Ecole Polytechnique F�d�rale de Lausanne
keywords: gcc bug O2
newsgroups: comp.unix.programmer,gnu.gcc.help,comp.os.linux.development.apps,comp.lang.c