🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.unix.programmer
27 messages
27 total messages Started by Mike Big Wed, 07 Aug 1996 00:00
gcc -O2 bug
#3657
Author: Mike Big
Date: Wed, 07 Aug 1996 00:00
64 lines
2557 bytes
/* 
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);
}
Re: gcc -O2 bug
#3658
Author: Danette & Murray Root
Date: Thu, 08 Aug 1996 00:00
8 lines
973 bytes
On 7 Aug 1996 22:35:57 -0500, mrbig@freeside.fc.net (Mike Big) wrote
in comp.lang.c:

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

That's not a bug, that's the reason for the 'volatile' keyword.
Re: gcc -O2 bug
#3659
Author: 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
---------------------------------------------------------------------- 
Re: gcc -O2 bug
#3660
Author: 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
Re: gcc -O2 bug
#3661
Author: Dan Pop
Date: Thu, 08 Aug 1996 00:00
18 lines
1513 bytes
In <3209b0dc.0@epflnews.epfl.ch> Thomas.Wolf@di.epfl.ch (Thomas Wolf) writes:

>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?

Nope.  The compiler didn't determine anything about time(), it simply
put the test _before_ the loop and generated an infinite loop.  That is
what any decent optimizing compiler is supposed to do in such a case,
since the expression being tested is a loop invariant.

Dan
--
Dan Pop
CERN, CN Division
Email: Dan.Pop@cern.ch 
Mail:  CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Re: gcc -O2 bug
#3662
Author: Bryan Ischo
Date: Thu, 08 Aug 1996 00:00
83 lines
3838 bytes
In article <danpop.839504721@news.cern.ch> Dan.Pop@cern.ch (Dan Pop) writes:
   In <4ubnat$75u@freeside.fc.net> mrbig@freeside.fc.net (Mike Big) writes:

[stuff skipped]

   >#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 */

[more skippage]

   >    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);

[skipped]

Just out of curiosity ... why can't the compiler be sure that 'flag' won't be
modified by printf?  After all, its type is declared as int, not int *, and
the loop conditional is 'while(flag)' not 'while (*flag)'.  What I'm getting
at is, the only way flag could be modified is if the programmer is assuming
that the size of an int is the same as the size of an int * and is passing in
an int in place of an int *, presumably one which has been casted from an
int * somewhere earlier.  And even then, the loop conditional is
'while(flag)', not 'while(*flag)', so even in the case that 'flag' was really
an int * in disguise, it never gets dereferenced anyhere.

Shouldn't the compiler be smart enough to know that flag can't be modified
even IF the printf is in the loop, given how smart it's been about everything
else?

Thanks,
Bryan


-- 
------------------------------------------------------------------------
Bryan Ischo                                    mailto:bji@connectinc.com
Mountain View, CA, USA                         http://www.connectinc.com
Linux Aficionado                                         1990 Honda CB-1
Re: gcc -O2 bug
#3663
Author: Peter Seebach
Date: Thu, 08 Aug 1996 00:00
40 lines
2412 bytes
In article <vkohklaizj.fsf@atari.connectinc.com>,
Bryan Ischo <bji@connectinc.com> wrote:
>Just out of curiosity ... why can't the compiler be sure that 'flag' won't be
>modified by printf?

Because it could be modified by printf.

>After all, its type is declared as int, not int *, and
>the loop conditional is 'while(flag)' not 'while (*flag)'.

So?  &flag generates a pointer to it, through which it could be modified, and
any call to any function could possibly refer to it.  Trivally,
	printf("%n", &flag);
would be stupid but would modify flag.

>What I'm getting
>at is, the only way flag could be modified is if the programmer is assuming
>that the size of an int is the same as the size of an int * and is passing in
>an int in place of an int *, presumably one which has been casted from an
>int * somewhere earlier.

This is simply untrue.  The programmer could have put flag's address in a
global, and a function named printf might modify the contents.

At least, I think what you're saying is untrue; I can't honestly understand a
word of it.

>Shouldn't the compiler be smart enough to know that flag can't be modified
>even IF the printf is in the loop, given how smart it's been about everything
>else?

Some versions might be, but it's an unlikely assumption.

-s
-- 
Peter Seebach - seebs@solon.com - Copyright 1996 - http://www.solon.com/~seebs
Unix/C Wizard - send mail for help, or send money for consulting!
The *other* C FAQ, the hacker FAQ, et al.  See web page above.
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.
Re: gcc -O2 bug
#3664
Author: Orc
Date: Thu, 08 Aug 1996 00:00
19 lines
1324 bytes
In article <4ubnat$75u@freeside.fc.net>,
Mike Big <mrbig@freeside.fc.net> wrote:
>/* 
>I'v found what I think might be a bug in gcc's optimization.

Not a bug; a feature.

Your code is being optimised away; gcc thinks that 'while(flag)'
is always true when you optimize with -O2.

If you convert your flag declaration to 'volatile int flag;' it will
subvert the optimisations.  (Check the ANSI standard; the code you've
got is almost the textbook example of why 'volatile' was created.)


                 ____
   david parsons \bi/ followups set to the proper place.
                  \/
Re: gcc -O2 bug
#3665
Author: Preston F. Crow
Date: Thu, 08 Aug 1996 00:00
85 lines
3767 bytes
As someone else pointed out already, the problem is that gcc will
optimize the loop, recognizing that there's nothing in the loop that
can modify 'flag,' so the test is performed only once (if even then).
The most surprising thing to me is that adding printf() results in the
loop working.  This ultimately makes sense, though, as the compiler
doesn't know for certain that printf() doesn't have a pointer to flag,
so it can't assume that it won't be modified.  As printf() takes
pointer arguments, the prototype can't use the gcc extensions to tell
the compiler that it won't have side effects.  I suspect that most
versions of the include files don't have those extensions, anyway,
though I would hope that especially the math functions would.

--PC

For reference:

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.)

>#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 position and/or opinions in the above message are those of the Board of
Trustees of Dartmouth College.  Copyright (c) 1996.  All right reserved.  The
above positions are also held by Newt Gingrich, many foriegn world leaders, and
you who are reading them.  Preston bears no responsibility for the content.
Re: gcc -O2 bug
#3666
Author: Dan Pop
Date: Thu, 08 Aug 1996 00:00
71 lines
3365 bytes
In <vkohklaizj.fsf@atari.connectinc.com> bji@connectinc.com (Bryan Ischo) writes:

>In article <danpop.839504721@news.cern.ch> Dan.Pop@cern.ch (Dan Pop) writes:
>   In <4ubnat$75u@freeside.fc.net> mrbig@freeside.fc.net (Mike Big) writes:
>
>   >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 */
>
>[more skippage]
>
>   >    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);
>
>[skipped]
>
>Just out of curiosity ... why can't the compiler be sure that 'flag' won't be
>modified by printf? 

Because flag is accessible via the flag_pt pointer, which is a global
variable, hence available to any function called by the program.
 
>Shouldn't the compiler be smart enough to know that flag can't be modified
>even IF the printf is in the loop, given how smart it's been about everything
>else?

On the contrary, it is smart enough to know that flag CAN be modified by
a function called within the loop.

Dan
--
Dan Pop
CERN, CN Division
Email: Dan.Pop@cern.ch 
Mail:  CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Re: gcc -O2 bug
#3667
Author: Bryan Ischo
Date: Thu, 08 Aug 1996 00:00
26 lines
1754 bytes
In article <vkn3059yhu.fsf@atari.connectinc.com> bji@connectinc.com (Bryan
Ischo) writes:
>   In article <4udd3i$90k@solutions.solon.com> seebs@solutions.solon.com
>   (Peter Seebach) writes:
>   >   This is simply untrue.  The programmer could have put flag's address
>   >   in a global, and a function named printf might modify the contents.
>   >

Oops.  Forget everything else I said.  This is the statement I missed which
makes everything clear.

Of course flag could be modified since another variable may contain a pointer
to it which may be passed into printf.  I just kind of missed that line of
thought altogether.

Duh.  My apologies for my density.

Best wishes,
Bryan

-- 
------------------------------------------------------------------------
Bryan Ischo                                    mailto:bji@connectinc.com
Mountain View, CA, USA                         http://www.connectinc.com
Linux Aficionado                                         1990 Honda CB-1
Re: gcc -O2 bug
#3668
Author: Peter Seebach
Date: Thu, 08 Aug 1996 00:00
58 lines
2888 bytes
In article <vkn3059yhu.fsf@atari.connectinc.com>,
Bryan Ischo <bji@connectinc.com> wrote:
>In article <4udd3i$90k@solutions.solon.com> seebs@solutions.solon.com
>(Peter Seebach) writes:
>C arguments are passed in by value, not by reference.  So, if I write a
>function which takes an int as an argument, then the function will NOT be able
>to modify the "original" value.  For example:

Correct.

>Now, the only way for me to write and use foo() with the same signature which
>modifies b is to do something like this:

Nope...

>Note that this REQUIRES that sizeof(int) == sizeof(int *).  Not a very robust
>programming practice.

It certainly isn't.  But consider:

	extern int *gptr;
	void foo(int a) {
		*gptr += 1;
	}

	void bar(void) {
		int b = 1;
		gptr = &b;
		foo(a);
	}

Neat, huh?

>True, but &flag was not passed in to printf in the original code.  What I am
>getting at is, 'flag' in the original code was only ever used as an integer
>and was only ever passed by value, so it could not be modified.  Maybe
>compilers aren't written to cover rules as specific as this, but it would be
>possible.  I mean, the whole notion of "volatile" is complicated enough to
>require similarly convoluted optimization logic.

The main problem is that, while looking inside the loop code, you can't be
sure *no one* has gotten the address of flag.  Or rather, you can, but the
compiler doesn't, so it assumes that any external function may have *side
effects* which modify flag.

>And I was just asking for confirmation of this idea.

Your understanding is correct; you are merely failing to account for the
idiocy of programmers, which most optimizers choose to accept rather than
second-guessing.

-s
-- 
Peter Seebach - seebs@solon.com - Copyright 1996 - http://www.solon.com/~seebs
Unix/C Wizard - send mail for help, or send money for consulting!
The *other* C FAQ, the hacker FAQ, et al.  See web page above.
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.
Re: gcc -O2 bug
#3669
Author: Bryan Ischo
Date: Thu, 08 Aug 1996 00:00
108 lines
4628 bytes
In article <4udd3i$90k@solutions.solon.com> seebs@solutions.solon.com
(Peter Seebach) writes:
>   In article <vkohklaizj.fsf@atari.connectinc.com>,
>   Bryan Ischo <bji@connectinc.com> wrote:
>   >Just out of curiosity ... why can't the compiler be sure that 'flag' 
>   >won't be modified by printf?
>
>   Because it could be modified by printf.
>
>   >After all, its type is declared as int, not int *, and
>   >the loop conditional is 'while(flag)' not 'while (*flag)'.
>
>   So?  &flag generates a pointer to it, through which it could be modified,
>   and any call to any function could possibly refer to it.  Trivally,
>	   printf("%n", &flag);
>   would be stupid but would modify flag.
>
>   >What I'm getting at is, the only way flag could be modified is if the
>   >programmer is assuming that the size of an int is the same as the size
>   >of an int * and is passing in an int in place of an int *, presumably
>   >one which has been casted from an int * somewhere earlier.
>
>   This is simply untrue.  The programmer could have put flag's address in a
>   global, and a function named printf might modify the contents.
>
>   At least, I think what you're saying is untrue; I can't honestly 
>   understand a word of it.
>
>   >Shouldn't the compiler be smart enough to know that flag can't be
>   >modified even IF the printf is in the loop, given how smart it's been
>   >about everything else?
>
>   Some versions might be, but it's an unlikely assumption.

OK, I'm sure I'll be corrected if I am wrong, but ...

C arguments are passed in by value, not by reference.  So, if I write a
function which takes an int as an argument, then the function will NOT be able
to modify the "original" value.  For example:

void foo(int a)
{
  a = a + 1;
}

void bar()
{
  int b = 3;

  foo(b);  
}

The call to foo() does NOT affect b's value in bar().  In foo(), 'a' will start
out as 3 and will increment to 4, and then promptly be popped off the stack
when the call to foo() returns.  b will be 3 before foo is called, and will
still be 3 afterwards.

Now, the only way for me to write and use foo() with the same signature which
modifies b is to do something like this:

void foo(int a)
{
   int *pa = (int *)a;

   *pa = *pa + 1;
}

void bar()
{
  int b = 3;

  foo((int)&b);
}

Note that this REQUIRES that sizeof(int) == sizeof(int *).  Not a very robust
programming practice.

What I was getting at before is, the compiler ought to be able to assume that
an int argument cannot be modified.  Sure, we could fudge foo and bar like we
did above, but that presumes things about the architecture that the compiler
ought not to allow, or at least ought to generate some pretty serious warnings
about.

To address some of the points from above ...

>   So?  &flag generates a pointer to it, through which it could be modified,
>   and any call to any function could possibly refer to it.  Trivally,
>	   printf("%n", &flag);
>   would be stupid but would modify flag.

True, but &flag was not passed in to printf in the original code.  What I am
getting at is, 'flag' in the original code was only ever used as an integer
and was only ever passed by value, so it could not be modified.  Maybe
compilers aren't written to cover rules as specific as this, but it would be
possible.  I mean, the whole notion of "volatile" is complicated enough to
require similarly convoluted optimization logic.

And I was just asking for confirmation of this idea.

Best wishes,
Bryan

-- 
------------------------------------------------------------------------
Bryan Ischo                                    mailto:bji@connectinc.com
Mountain View, CA, USA                         http://www.connectinc.com
Linux Aficionado                                         1990 Honda CB-1
Re: gcc -O2 bug
#3670
Author: 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.
Re: gcc -O2 bug
#3671
Author: Danette & Murray Root
Date: Fri, 09 Aug 1996 00:00
24 lines
1640 bytes
On 8 Aug 1996 21:51:37 +0100, guenter@castle.dinoco.de (Heinz Guenter
Scharf) wrote in comp.lang.c:


=>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.

Why not just use the keyword 'volatile' ? Does gcc not support it?
(pardon me - I don't [currently] use gcc).
Re: gcc -O2 bug
#3672
Author: Lawrence Kirby
Date: Fri, 09 Aug 1996 00:00
34 lines
2333 bytes
In article <4ubogp$e8a@mule1.mindspring.com>
           mroot@atl.mindspring.com "Danette & Murray Root" writes:

>On 7 Aug 1996 22:35:57 -0500, mrbig@freeside.fc.net (Mike Big) wrote
>in comp.lang.c:
>
>=>/* 
>=>I'v found what I think might be a bug in gcc's optimization.  The
>
>That's not a bug, that's the reason for the 'volatile' keyword.

And also sig_atomic_t. What the code actually violates is (ISO 7.7.1.1):

"If the signal occurs other than as the result of calling the abort or
 raise function, the behaviour is undefined if the signal handler calls
 any function in the standard library other than the signal function
 itself (with a first argument 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 storage
 duration variable of type volatile sig_atomic_t."

This allows the compiler to optimise the foreground loop without breaking the
standard. As you can see there is very little that you can do in a signal
handler and remain as strictly conforming C. You can perform calculations
using auto variables and notify events/state changes back to the foreground
code through static variables of type volatile sig_atomic_t which the
foreground code has to poll.

-- 
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
Re: gcc -O2 bug
#3673
Author: Christopher R Volpe
Date: Fri, 09 Aug 1996 00:00
40 lines
2293 bytes
Bryan Ischo wrote:
> 
> In article <4udd3i$90k@solutions.solon.com> seebs@solutions.solon.com
> (Peter Seebach) writes:
> >   Some versions might be, but it's an unlikely assumption.
> 
> OK, I'm sure I'll be corrected if I am wrong, but ...
> 
> C arguments are passed in by value, not by reference.  So, if I write a
> function which takes an int as an argument, then the function will NOT be able
> to modify the "original" value.  For example:

You're missing the point here. Let us assume for the moment that the
compiler proper is unaware of any special semantics associated with the
printf function. For all the compiler knows, there may be a a file
called printf.c that contains the following:

/* File printf.c */
extern int *flag_pt;
extern int getpid(); /* keep this relevant to comp.unix.programmer :) */
int printf(char *s, int a, int b, int c)
{
  *flag_pt = a + b;
   return c;
}


See why the compiler can't presume that flag doesn't get modified?

comp.std.c answer: The compiler is allowed to know the semantics of
printf, and should know that the printf function will not modify
flag_pt, despite the fact that other user-defined functions could.

--

Chris Volpe			Phone: (518) 387-7766 
GE Corporate R&D		Fax:   (518) 387-6560
PO Box 8 			Email: volpecr@crd.ge.com
Schenectady, NY 12301		Web:   http://www.crd.ge.com/~volpecr
Re: gcc -O2 bug
#3674
Author: John Hasler
Date: Fri, 09 Aug 1996 00:00
16 lines
1318 bytes
Thomas Wolf writes:
> How your compiler determined that 'time' does not return something
> that results in 'flag' == 0 is a mystery to me.

I don't think it did.  I think it converted the loop into a test of 'flag'
and an infinite loop, and jumped either over or into the loop depending
on the value of 'flag'.

-- 


John Hasler		   This posting is in the public domain.
jghasler@win.bright.net	   Do with it what you will.
Dancing Horse Hill	   Make money from it if you can; I don't mind.
Elmwood, Wisconsin
Re: gcc -O2 bug
#3675
Author: Preston F. Crow
Date: Sat, 10 Aug 1996 00:00
23 lines
1782 bytes
Christopher R Volpe <volpe@ash.crd.ge.com> writes:

>comp.std.c answer: The compiler is allowed to know the semantics of
>printf, and should know that the printf function will not modify
>flag_pt, despite the fact that other user-defined functions could.

No, the compiler can't assume anything about printf(), as the user
could have stupidly defined his own function of the same name,
overriding the expected behaviour of the version in libc.

In some of my Mach programming, I've done just that.  [Well, with
different functions, where the normal version had problems, but
still...]

Never expect a compiler to be smart, but always be prepared for it to
outsmart you.

--PC
--
We're sorry, the .sig you have selected has been deleted or is no longer in
service.  If you think you have read this .sig in error, please disconnect
and try your news reader again.  Thank-you.
Re: gcc -O2 bug
#3676
Author: Orc
Date: Sat, 10 Aug 1996 00:00
42 lines
2628 bytes
In article <danpop.839541415@news.cern.ch>, Dan Pop <Dan.Pop@cern.ch> wrote:
>In <vkohklaizj.fsf@atari.connectinc.com> bji@connectinc.com (Bryan Ischo) writes:
>
>>In article <danpop.839504721@news.cern.ch> Dan.Pop@cern.ch (Dan Pop) writes:
>>   In <4ubnat$75u@freeside.fc.net> mrbig@freeside.fc.net (Mike Big) writes:
>>
>>   >int *flag_pt;
>>   >
    [snip]
>>   >  while(flag){ /* does NOT exit when using gcc -O2 */
>>
>>[more skippage]
>>
>>   >    counter++;
>>   >    /* uncomenting the printf below will fix things. weird heh */
>>
>>Just out of curiosity ... why can't the compiler be sure that 'flag' won't be
>>modified by printf? 
>
>Because flag is accessible via the flag_pt pointer, which is a global
>variable, hence available to any function called by the program.
> 
>>Shouldn't the compiler be smart enough to know that flag can't be modified
>>even IF the printf is in the loop, given how smart it's been about everything
>>else?
>
>On the contrary, it is smart enough to know that flag CAN be modified by
>a function called within the loop.

... but not smart enough to know that flag can be manipulated by a
signal driven function while the loop is running.   Isn't optimization
fun?  My first reaction, if I was still writing compilers, to assigning
a variable's address to a global would be to treat the variable as a
volatile from there on in, but I'm sure I could independently come up
with pretty much the same reasons as the ANSI committee did for why
that's not necessarily a good thing.

                 ____
   david parsons \bi/ It's better to be a firewall hacker; the pay is better
                  \/   and you only have to deal with people trying to break
		                                                          in.
Re: gcc -O2 bug
#3677
Author: Mike Rubenstein
Date: Sat, 10 Aug 1996 00:00
28 lines
2028 bytes
crow@coos.dartmouth.edu (Preston F. Crow) wrote:

> Christopher R Volpe <volpe@ash.crd.ge.com> writes:
> 
> >comp.std.c answer: The compiler is allowed to know the semantics of
> >printf, and should know that the printf function will not modify
> >flag_pt, despite the fact that other user-defined functions could.
> 
> No, the compiler can't assume anything about printf(), as the user
> could have stupidly defined his own function of the same name,
> overriding the expected behaviour of the version in libc.
> 
> In some of my Mach programming, I've done just that.  [Well, with
> different functions, where the normal version had problems, but
> still...]
> 
> Never expect a compiler to be smart, but always be prepared for it to
> outsmart you.

NO.  The compiler may assume that you have not replaced printf() with
another function.  Replacing a standard library function results in
undefined behavior -- the compiler may do anything.  See ISO 7.1.3.

Just because some compiler allowed you to do this, does not mean it is
legal.

Michael M Rubenstein
Re: gcc -O2 bug
#3678
Author: Lawrence Kirby
Date: Sat, 10 Aug 1996 00:00
39 lines
2635 bytes
In article <4uh4vh$aj2@dartvax.dartmouth.edu>
           crow@coos.dartmouth.edu "Preston F. Crow" writes:

>Christopher R Volpe <volpe@ash.crd.ge.com> writes:
>
>>comp.std.c answer: The compiler is allowed to know the semantics of
>>printf, and should know that the printf function will not modify
>>flag_pt, despite the fact that other user-defined functions could.
>
>No, the compiler can't assume anything about printf(), as the user
>could have stupidly defined his own function of the same name,
>overriding the expected behaviour of the version in libc.

No, this isn't how it works. printf is a reserved identifier with external
linkage which means that if you try to define it yourself with external
linkage the behaviour is undefined. Also if you include stdio.h you can't
define printf yourself at file scope, for example you can't define a
static printf function. The standard is deliberately worded so that the
implementation can make assumptions about standard library functions. This
allows compilers, for example, to implicitly inline memcpy, strcpy etc.

>In some of my Mach programming, I've done just that.  [Well, with
>different functions, where the normal version had problems, but
>still...]

It may work on your compiler but the language gives you no guarantees
at all that it will.

>Never expect a compiler to be smart, but always be prepared for it to
>outsmart you.

Exactly.

-- 
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
Re: gcc -O2 bug
#3679
Author: Lawrence Kirby
Date: Sat, 10 Aug 1996 00:00
27 lines
1971 bytes
In article <4uhp4i$pmu@pell.pell.chi.il.us> orc@pell.chi.il.us "Orc" writes:

...

>... but not smart enough to know that flag can be manipulated by a
>signal driven function while the loop is running.

It is smart enough to know that the language says it doesn't have to
worry about this. Instead it can concentrate on generatingh efficient
code.

>  Isn't optimization
>fun?  My first reaction, if I was still writing compilers, to assigning
>a variable's address to a global would be to treat the variable as a
>volatile from there on in, but I'm sure I could independently come up
>with pretty much the same reasons as the ANSI committee did for why
>that's not necessarily a good thing.

This simply comes down to knowing the language that you are programming
in. C is quite clear about what you are allowed to do in signal handlers.

-- 
-----------------------------------------
Lawrence Kirby | fred@genesis.demon.co.uk
Wilts, England | 70734.126@compuserve.com
-----------------------------------------
Re: gcc -O2 bug
#3680
Author: Orc
Date: Sat, 10 Aug 1996 00:00
50 lines
3048 bytes
In article <839695541snz@genesis.demon.co.uk>,
Lawrence Kirby  <fred@genesis.demon.co.uk> wrote:
>In article <4uhp4i$pmu@pell.pell.chi.il.us> orc@pell.chi.il.us "Orc" writes:
>
>...
>
>>... but not smart enough to know that flag can be manipulated by a
>>signal driven function while the loop is running.
>
>It is smart enough to know that the language says it doesn't have to
>worry about this. Instead it can concentrate on generatingh efficient
>code.

It's a matter of opinion.  I happen to agree with the ANSI committee
that it's not something that happens enough to worry about, but you'll
have to quote chapter and verse if you're going to say that the
'language says it doesn't have to worry about this' when you attempt
to agree with me as your crushing rebuttal.


>>  Isn't optimization
>>fun?  My first reaction, if I was still writing compilers, to assigning
>>a variable's address to a global would be to treat the variable as a
>>volatile from there on in, but I'm sure I could independently come up
>>with pretty much the same reasons as the ANSI committee did for why
>>that's not necessarily a good thing.
>
>This simply comes down to knowing the language that you are programming
>in.

Don't be stupid.  Read up on 'noalias' if you want to see some of the
thinking that's gone into what's allowable and not; and when you're
done with that, please reread the quoted section of my post again,
paying careful attention this time to the phrases '... My first reaction
...' and '... but I'm sure I could independently come up with ...'  The
business of developing a standard isn't just sitting around waiting for
the Hand Of God to deliver the first draft to you on neatly typed
parchment; people do, as I pointed out in my post, need to think about
the consequences of allowing and disallowing certain types of behavior.


>C is quite clear about what you are allowed to do in signal handlers.

In a ANSI conformant run-time library, possibly.  Pity none of them
exist, isn't it? (*)

                ____
  david parsons \bi/ (* And this is why the damned standard was written in
                 \/     the first place.)
Re: gcc -O2 bug
#3681
Author: Christopher R Volpe
Date: Mon, 12 Aug 1996 00:00
31 lines
2099 bytes
Preston F. Crow wrote:
> 
> Christopher R Volpe <volpe@ash.crd.ge.com> writes:
> 
> >comp.std.c answer: The compiler is allowed to know the semantics of
> >printf, and should know that the printf function will not modify
> >flag_pt, despite the fact that other user-defined functions could.
> 
> No, the compiler can't assume anything about printf(), as the user

Bzzzt. Thanks for playing.

> could have stupidly defined his own function of the same name,
             ^^^^^^^^
And the reason this would be "stupid" is that it's not legal for him to
do so, since the compiler is allowed to know what printf does.

> overriding the expected behaviour of the version in libc.
> 
> In some of my Mach programming, I've done just that.  [Well, with

"The behavior is undefined", even if you were (un)lucky enough to have
it do what you wanted.

--

Chris Volpe			Phone: (518) 387-7766 
GE Corporate R&D		Fax:   (518) 387-6560
PO Box 8 			Email: volpecr@crd.ge.com
Schenectady, NY 12301		Web:   http://www.crd.ge.com/~volpecr
Re: gcc -O2 bug
#3682
Author: Preston F. Crow
Date: Mon, 12 Aug 1996 00:00
46 lines
3037 bytes
Christopher R Volpe <volpe@ash.crd.ge.com> writes:
>Preston F. Crow wrote:
>> Christopher R Volpe <volpe@ash.crd.ge.com> writes:
>> 
>> >comp.std.c answer: The compiler is allowed to know the semantics of
>> >printf, and should know that the printf function will not modify
>> >flag_pt, despite the fact that other user-defined functions could.
>> 
>> No, the compiler can't assume anything about printf(), as the user

>Bzzzt. Thanks for playing.

>> could have stupidly defined his own function of the same name,
>             ^^^^^^^^
>And the reason this would be "stupid" is that it's not legal for him to
>do so, since the compiler is allowed to know what printf does.

>> overriding the expected behaviour of the version in libc.
>> 
>> In some of my Mach programming, I've done just that.  [Well, with

>"The behavior is undefined", even if you were (un)lucky enough to have
>it do what you wanted.

Ahh, but it is defined for a given compiler implementation, and since
we're obviously talking about gcc (note the newsgroups) running under
Linux (note the newsgroups), the behaviour is defined as to allow it
to work, so long as you take all or none of the symbols from a given
source file for the library.  Exceptions are made for functions like
exit() and abort() for which gcc knows that they don't return.
Functions like printf() will generate warnings unless your version
uses a similar prototype with arguments based on the format string.

One example of why you might want to redefine printf() to have an
unexpected side-effect would be in developing and testing a new libc.
You might want to record information about the execution of printf()
in global variables which are then examined in the main program.  (Of
course, you're probably better off using a debugger...)

--PC
--
=========================================================================
"It is perhaps only in mathematics that the means of study are also the
objects of study."  _The Handbook of Artificial Intelligence, Vol. 3,
                    page 445.
Re: gcc -O2 bug
#3656
Author: Alan Lehotsky
Date: Wed, 14 Aug 1996 00:00
47 lines
2652 bytes
In article <4uo8it$ogu@dartvax.dartmouth.edu>, crow@coos.dartmouth.edu
(Preston F. Crow) wrote:

>>>Christopher R Volpe <volpe@ash.crd.ge.com> writes:
>>>>Preston F. Crow wrote:
>>>>> Christopher R Volpe <volpe@ash.crd.ge.com> writes:
>>>>> 
>>>>> >comp.std.c answer: The compiler is allowed to know the semantics of
>>>>> >printf, and should know that the printf function will not modify
>>>>> >flag_pt, despite the fact that other user-defined functions could.
>>>>> 
>>>>> No, the compiler can't assume anything about printf(), as the user
>>>
>>>>Bzzzt. Thanks for playing.

  1/ You should be able to turn this behavior off with

      -fno-builtins

  2/ ANSI says (4.1.2.1)

      ...If the program declares or defines an identifier with the
      same name as an identifier reserved in that context (other than
      allowed by 4.1.6) the behavior is undefined.

     The 'that context' refers to reserved identifiers declared in the
     library header files.

So, my interpretation is that:

   a. RTFM (or RTF info-files, in the case of gcc), and you can
      dumb-down the compiler.

   b. ANSI allows a compiler to do strange and wonderous things to
      recognize those names provided by the standard library header
      files.

-- Al Lehotsky

-- 
                    Quality Software Management
                  (617)862-5418 (617)674-1096 FAX
                        lehotsky@tiac.net
                 http://www.tiac.net/users/lehotsky
                   Software Process Improvement
                      Management Consulting
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads