This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: New const function detection code and infinite loops.



  Well and for example following function:

  int funct(int b)
  {
    while(b&1) b+=2;
    return b;
  }
  main()
  { 
    funct(1);
  }
  despite the fact, that function is complette nonsence, it still contains
  infinite loop (for certain input values), but will be marked as const by
  the detection code.

If I follow, you're saying that some part of the compiler works like
this:
 
  1. A `const' function is one that doesn't read or write any global
     memory.  This is automatically detected, and `funct' is marked
     as `const'.
  2. Therefore, a `const' function has no side-effects.
  3. Therefore, if the value of a `const' function is not used, the
     call to the `const' function can be omitted.

The GCC documentation for the `const' attribute says:

  Many functions do not examine any values except their arguments,
  and have no effects except the return value.

As you note, running forever *is* an effect.  Therefore, `funct' is
not `const'.  Therefore, the const-detection code should not detect
this case.  It could be conservative by not including any function
with a loop (including a goto), or a function call.  (Because a
function call could indicate recursion.  I guess you could technically
ignore function calls; if that's the way by which you get infinite
looping then you'll get a stack overflow, which is undefined behavior,
which means that you can do anything you want.  But, I think it would
be better to treat function calls like potential loops.)

Some other attribute (I think this is the `pure' attribute) *does*
apply to such functions.  It says that this function may have loop
forever, but is guaranteed to return the same value whenever it is
called with the same arguments, and does not affect global memory.
So, you can turn `funct (1) + funct (1)' into `2 * funct(1)', or even
`funct (1)', if you're not using the value.

(BTW, technically, your program has undefined behavior because `b'
will overflow.  If you made `b' an unsigned int, the behavior would be
defined.)

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]