title: C++ compile time program wide unique numbers
body: <p>I've come up with a solution to a problem but I'm not sure if it'll always work or just on my compiler. First, the problem: I've noticed in a number of situations it's desirable to have a template class that gets re-instantiated each time it's used even when given the same types (say your template class has static members that are initialized to function calls that have some important side effect -- and you want this side effect to be done every time the template is used). The easy way to do this is to give your template an extra integer parameter:</p>
  
  <pre><code>template&lt;class T, class U, int uniqueify&gt;
  class foo
  {
  ...
  }
  </code></pre>
  
  <p>But now you have to manually make sure that every time you use foo you pass it a different value for uniqueify. The naive solution is to use <code>__LINE__</code> like this:</p>
  
  <pre><code>#define MY_MACRO_IMPL(line) foo&lt;line&gt;
  #define MY_MACRO MY_MACRO_IMPL(__LINE__)
  </code></pre>
  
  <p>This solution has an issue though -- <code>__LINE__</code> gets reset for each translation unit. So if two translation units use the template on the same line, the template only gets instantiated once. That may seem unlikely, but imagine how difficult to debug the compiler error it would be if it did happen. Similarly you could try using <code>__DATE__</code> as a parameter somehow, but that only has seconds precision and it's the time when compiling started, not when it reaches that line, so if you're using a parallel version of make it's rather plausible to have two translation units with the same <code>__DATE__</code>.</p>
  
  <p>Another solution is that some compilers have a special non-standard macro, <code>__COUNTER__</code> that starts at 0 and increments every time you use it. But it suffers from the same problem -- it gets reset for each invocation of the preprocessor, so it gets reset each translation unit.</p>
  
  <p>Yet another solution, is to use <code>__FILE__</code> and <code>__LINE__</code> together:</p>
  
  <pre><code>#define MY_MACRO_IMPL(file, line) foo&lt;T, U, file, line&gt;
  #define MY_MACRO MY_MACRO_IMPL(T, U, __FILE__, __LINE__)
  </code></pre>
  
  <p>But you can't pass char literals as template parameters according to the standard because they don't have external linkage.</p>
  
  <p>Even if this did work, whether <code>__FILE__</code> contains the absolute path to the file or just the name of the file itself isn't defined in the standard, so if you had two identical named files in different folders, this could still break. So here is my solution:</p>
  
  <pre><code>#ifndef toast_unique_id_hpp_INCLUDED
  #define toast_unique_id_hpp_INCLUDED
  
  namespace {
  namespace toast {
  namespace detail {
  
  template&lt;int i&gt;
  struct translation_unit_unique {
      static int globally_unique_var;
  };
  
  template&lt;int i&gt;
  int translation_unit_unique&lt;i&gt;::globally_unique_var;
  
  }
  }
  }
  
  #define TOAST_UNIQUE_ID_IMPL(line) &amp;toast::detail::translation_unit_unique&lt;line&gt;::globally_unique_var
  #define TOAST_UNIQUE_ID TOAST_UNIQUE_ID_IMPL(__LINE__)
  
  #endif
  </code></pre>
  
  <p>Why this works isn't really clear without a usage example, but first an overview. The key insight I had was to see that every time you make a global variable or a static member variable, you're creating a program wide unique number in the form of the address of that variable. So this gives us a unique number that's available at compile time. <code>__LINE__</code> makes sure we won't get clashes within the same translation unit, and the outer anonymous namespace makes sure the variables are different instances (and thus get differing addresses) across translation units.</p>
  
  <p>Example usage:</p>
  
  <pre><code>template&lt;int* unique_id&gt;
  struct special_var
  {
      static int value;
  }
  
  template&lt;int* unique_id&gt;
  int special_var&lt;unique_id&gt;::value = someSideEffect();
  
  #define MY_MACRO_IMPL(unique_id) special_var&lt;unique_id&gt;
  #define MY_MACRO MY_MACRO_IMPL(TOAST_UNIQUE_ID)
  </code></pre>
  
  <p>And foo.cpp becomes:</p>
  
  <pre><code>#include &lt;toast/unique_id.hpp&gt;
  
  ...
  
  typedef MY_MACRO unique_var;
  typedef MY_MACRO unique_var2;
  unique_var::value = 3;
  unique_var2::value = 4;
  std::cout &lt;&lt; unique_var::value &lt;&lt; unique_var2::value;
  </code></pre>
  
  <p>Despite being the same template, and the user providing no differentiating parameters, <code>unique_var</code> and <code>unique_var2</code> are distinct.</p>
  
  <p>I'm mostly worried about the address in of the variable in the anonymous namespace actually being available at compile time. Technically, an anonymous namespace is like declaring internal linkage, and template parameters can't have internal linkage. But the way the standard says to treat anonymous namespaces is just like the variable was declared as part of a namespace with a program-wide unique name, which means that technically it <em>does</em> have external linkage, even though we don't usually think of it as such. So I think the standard is on my side, but I'm not sure.</p>
  
  <p>I don't know if I've done the best job of explaining <em>why</em> this would be useful, but for the sake of this discussion, it is, I swear ;)</p>