This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/58281] New: Problem with explicit constexpr template functions
- From: "bmerry at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 30 Aug 2013 13:10:52 +0000
- Subject: [Bug c++/58281] New: Problem with explicit constexpr template functions
- Auto-submitted: auto-generated
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)