http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58281
Bug ID: 58281 Summary: Problem with explicit constexpr template functions Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: bmerry at gmail dot com Created attachment 30730 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30730&action=edit Minimal broken test case It seems that in some cases explicit instantiation of a function template fails to actually instantiate anything. A minimal example (also attached) is template<typename T> constexpr bool f(T a) { return a == 3; } extern template bool f<int>(int); bool g(int x) { return f(x); } template bool f<int>(int); int main() { return g(4); } for which compilation gives $ g++-4.8 -std=c++11 -o instantiate instantiate.cpp /tmp/ccPWHA9d.o: In function `g(int)': instantiate.cpp:(.text+0x11): undefined reference to `bool f<int>(int)' collect2: error: ld returned 1 exit status Obviously in real usage the explicit instantiation declaration would be in a header and the explicit instantiation definition would be in a .cpp file, but it's all one translation unit either way. Some experimentation shows that any of following will compile: - moving function g to after the explicit instantiation definition - removing the constexpr qualifier from f - removing g and main entirely (nm shows the symbol for f<int> in the resulting .o file) The only relevant constraints I found in a quick search of the C++11 [draft] spec were in 14.7.2.11: "If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration. An entity that is the subject of an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit instantiation (14.7.1) in the translation unit shall be the subject of an explicit instantiation definition somewhere in the program; otherwise the program is ill-formed, no diagnostic required." which all seem to be satisfied by the example. System information: Ubuntu 12.04 on x86_64, running with GCC 4.8.1: Using built-in specs. COLLECT_GCC=g++-4.8 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.1-2ubuntu1~12.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.1 (Ubuntu 4.8.1-2ubuntu1~12.04)