title: How undefined are __builtin_ctz(0) or __builtin_clz(0)?
body: <h2>Background</h2>
  
  <p>For a long time, <a href="http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Other-Builtins.html">gcc has been providing</a> a number of builtin bit-twiddling functions, in particular the number of trailing and leading 0-bits (also for <code>long unsigned</code> and <code>long long unsigned</code>, which have suffixes <code>l</code> and <code>ll</code>):</p>
  
  <blockquote>
    <p>— Built-in Function: <code>int __builtin_clz (unsigned int x)</code> </p>
    
    <p>Returns the
    number of leading 0-bits in <code>x</code>, starting at the most significant bit
    position. If <code>x</code> is 0, the result is undefined.</p>
    
    <p>— Built-in Function: <code>int __builtin_ctz (unsigned int x)</code> </p>
    
    <p>Returns the
    number of trailing 0-bits in <code>x</code>, starting at the least significant bit
    position. If <code>x</code> is 0, the result is undefined.</p>
  </blockquote>
  
  <p>On every online (disclaimer: only x64) compiler I tested, however, the result has been that both <code>clz(0)</code> and <code>ctz(0)</code> return the number of bits of the underlying builtin type, e.g.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;limits&gt;
  
  int main()
  {
      // prints 32 32 32 on most systems
      std::cout &lt;&lt; std::numeric_limits&lt;unsigned&gt;::digits &lt;&lt; " " &lt;&lt; __builtin_ctz(0) &lt;&lt; " " &lt;&lt; __builtin_clz(0);    
  }
  </code></pre>
  
  <p><a href="http://coliru.stacked-crooked.com/a/cca9c181597cadb8"><strong>Live Example</strong></a>.  </p>
  
  <h2>Attempted workaround</h2>
  
  <p>The latest Clang SVN trunk in <code>std=c++1y</code> mode has made all these functions relaxed C++14 <code>constexpr</code>, which makes them candidates to use in a SFINAE expression for a wrapper function template around the 3 <code>ctz</code> / <code>clz</code> builtins for <code>unsigned</code>, <code>unsigned long</code>, and <code>unsigned long long</code></p>
  
  <pre><code>template&lt;class T&gt; // wrapper class specialized for u, ul, ull (not shown)
  constexpr int ctznz(T x) { return wrapper_class_around_builtin_ctz&lt;T&gt;()(x); }
  
  // overload for platforms where ctznz returns size of underlying type
  template&lt;class T&gt;
  constexpr auto ctz(T x) 
  -&gt; typename std::enable_if&lt;ctznz(0) == std::numeric_limits&lt;T&gt;::digits, int&gt;::type
  { return ctznz(x); }
  
  // overload for platforms where ctznz does something else
  template&lt;class T&gt;
  constexpr auto ctz(T x) 
  -&gt; typename std::enable_if&lt;ctznz(0) != std::numeric_limits&lt;T&gt;::digits, int&gt;::type
  { return x ? ctznz(x) : std::numeric_limits&lt;T&gt;::digits; }
  </code></pre>
  
  <p>The gain from this hack is that platforms that give the required result for <code>ctz(0)</code> can omit an extra conditional to test for <code>x==0</code> (which might seem a micro-optimization, but when you are already down to the level of builtin bit-twiddling functions, it can make a big difference)</p>
  
  <h2>Questions</h2>
  
  <p>How undefined is the family of builtin functions <code>clz(0)</code> and <code>ctz(0)</code>?</p>
  
  <ul>
  <li>can they throw an <code>std::invalid_argument</code> exception?</li>
  <li>for x64, will they for the current gcc distro return the size of the underyling type?</li>
  <li>are the ARM/x86 platforms any different (I have no access to that to test those)?</li>
  <li>is the above SFINAE trick a well-defined way to separate such platforms?</li>
  </ul>