title: Static *template* class member across dynamic library
body: <p>Edit: the comments below the accepted answer show that it might be an issue with the Android dynamic loader.</p>
  
  <p>I have a header for a template class with a static member. At runtime the address of the static member is used in the library and in the client code. The template is implicitly instantiated both in the library and in the client code. It works fine on Linux and OSX, the symbol is duplicated but marked as "uniqued" as shown by nm (see below).
  However when I compile for ARM (Android), the symbol is marked weak in both the DSO and the executable. The loader does not unify and the symbol is effectively duplicated at runtime!</p>
  
  <p>I read these:
  <a href="https://stackoverflow.com/questions/11666166/two-instances-of-a-static-member-how-could-that-be">two instances of a static member, how could that be?</a>
  <a href="https://stackoverflow.com/questions/4924082/static-template-data-members-storage">Static template data members storage</a>
  and especially this answer:
  <a href="https://stackoverflow.com/a/2505528/2077394">https://stackoverflow.com/a/2505528/2077394</a>
  and:
  <a href="http://gcc.gnu.org/wiki/Visibility" rel="nofollow noreferrer">http://gcc.gnu.org/wiki/Visibility</a></p>
  
  <p>but I am still a little bit puzzled. I understand that the attributes for visibility helps to optimize, but I thought it should work by default. I know the C++ standard does not care about shared library, but does it means that using shared libraries breaks the standard? (or at least this implementation is not C++ standard conform?)
  Bonus: how can I fix it? (and not using template is not an acceptable answer:))</p>
  
  <p>Header:</p>
  
  <pre><code>template&lt;class T&gt;
  struct TemplatedClassWithStatic {
      static int value;
  };
  template&lt;class T&gt;
  int TemplatedClassWithStatic&lt;T&gt;::value = 0;
  </code></pre>
  
  <p>shared.cpp:</p>
  
  <pre><code>#include "TemplateWithStatic.hpp"
  int *addressFromShared() {
      return &amp;TemplatedClassWithStatic&lt;int&gt;::value;   
  }
  </code></pre>
  
  <p>main.cpp:</p>
  
  <pre><code>#include "TemplateWithStatic.hpp"
  #include &lt;cstdio&gt;
  
  int *addressFromShared();
  int main() {
      printf("%p %p\n", addressFromShared(),  &amp;TemplatedClassWithStatic&lt;int&gt;::value);
  }
  </code></pre>
  
  <p>And building, looking at the symbols definitions:</p>
  
  <p>producing .so:</p>
  
  <pre><code> g++-4.8  -shared src/shared.cpp  -o libshared.so -I include/ -fPIC
  </code></pre>
  
  <p>compiling and linking main:</p>
  
  <pre><code> g++-4.8 src/main.cpp -I include/ -lshared -L.
  </code></pre>
  
  <p>symbols are marked as "unique":</p>
  
  <pre><code>nm -C -A *.so a.out | grep 'TemplatedClassWithStatic&lt;int&gt;::value'
  libshared.so:0000000000200a70 u TemplatedClassWithStatic&lt;int&gt;::value
  a.out:00000000006012b0 u TemplatedClassWithStatic&lt;int&gt;::value
  </code></pre>
  
  <p>producing .so</p>
  
  <pre><code>~/project/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-g++    -o libshared.so src/shared.cpp   -I include/  --sysroot=/Users/amini/project/android-ndk-r9/platforms/android-14/arch-arm/ -shared
  </code></pre>
  
  <p>compiling and linking main</p>
  
  <pre><code>~/project/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-g++  src/main.cpp  libshared.so    -I include/  --sysroot=${HOME}/project/android-ndk-r9/platforms/android-14/arch-arm/  -I ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/include -I ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/include/backward    -I ~/project/android-ndk-r9/platforms/android-14/arch-arm/usr/include  ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/libgnustl_static.a -lgcc
  </code></pre>
  
  <p>symbols are weak!</p>
  
  <pre><code>nm -C -A *.so a.out | grep 'TemplatedClassWithStatic&lt;int&gt;::value'
  libshared.so:00002004 V TemplatedClassWithStatic&lt;int&gt;::value
  a.out:00068000 V TemplatedClassWithStatic&lt;int&gt;::value
  </code></pre>
  
  <p>Edit, note for the context: I was playing with OOLua, a library helping binding C++ to Lua and my unittests were failing when I started to target Android. I don't "own" the code and I would rather modifying it deeply.</p>
  
  <p>Edit, to run it on Android:</p>
  
  <pre><code>adb push libshared.so data/local/tmp/
  adb push a.out data/local/tmp/ 
  adb shell "cd data/local/tmp/ ; LD_LIBRARY_PATH=./ ./a.out"
  0xb6fd7004 0xb004
  </code></pre>