title: GCC optimization of pure functions
body: <p>I am confused by the guarantees GCC makes about optimizing <code>pure</code> functions (from <a href="https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-optimize-function-attribute" rel="noreferrer">online docs</a>):</p>
  
  <blockquote>
  <pre><code>pure
  </code></pre>
    
    <p>Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables.
    (...)</p>
    
    <p>Interesting <strong>non-pure</strong> functions are functions with infinite loops or those depending on volatile memory or other system resources, that may change between two consecutive calls (such as <code>feof</code> in a multithreading environment).</p>
  </blockquote>
  
  <p>And for <code>const</code>:</p>
  
  <blockquote>
  <pre><code>const
  </code></pre>
    
    <p>Many functions do not examine any values except their arguments, and have no effects except the return value. Basically, this is just slightly more strict class than the pure attribute below, since the function is not allowed to read global memory.</p>
    
    <p><strong>Note that a function that has pointer arguments and examines the data pointed to must not be declared <code>const</code></strong>. Likewise, a function that calls a non-const function usually must not be const. </p>
  </blockquote>
  
  <p>So, I tried creating a function which does accept a pointer parameter, and tried marking it <code>pure</code>. However, I tried compiling this function using GCC online (I tried both <code>const</code> and <code>pure</code>):</p>
  
  <pre><code>typedef struct
  {
      int32_t start;
      int32_t end;
  }
  Buffer;
  
  inline __attribute__((pure,always_inline)) int32_t getLen(Buffer * b) 
  {
      return b-&gt;end - b-&gt;start;
  }
  </code></pre>
  
  <p>And noticed that GCC (at least the several <a href="https://godbolt.org/g/nbL2cY" rel="noreferrer">online compiler versions</a> I've tried):</p>
  
  <ol>
  <li><strong>doesn't optimize</strong> calls to this function (i.e. calls it multiple times) if the passed <code>Buffer*</code> parameter is pointing to a global value,</li>
  <li><strong>optimizes</strong> calls to this function (i.e. calls it only once), if the 
  passed pointer is pointing to a local (stack) variable.</li>
  <li>both cases work the same even if I mark the function <code>const</code> instead of <code>pure</code>, but presumably <code>const</code> is ignored if there is a pointer argument?</li>
  </ol>
  
  <p><strong>This is a good thing</strong>, because a global <code>Buffer</code> might change by a different thread/interrupt at any time, while a local <code>Buffer</code> is perfectly safe for optimizations.</p>
  
  <p>But I am completely confused by the remarks regarding passing pointers. Is there a place where the behavior of the GCC is explicitly defined for <code>pure</code> functions accepting pointer arguments?</p>