Opened 5 years ago
Last modified 5 years ago
#13191 new Bugs
undefined reference error when ODR-using boost::ratio::{num,den}
Reported by: | anonymous | Owned by: | viboes |
---|---|---|---|
Milestone: | To Be Determined | Component: | ratio |
Version: | Boost 1.59.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Attachments (1)
Change History (5)
by , 5 years ago
Attachment: | ratiosymbol.tgz added |
---|
comment:1 by , 5 years ago
Summary: | undefined symbol → undefined reference error when ODR-using boost::ratio::{num,den} |
---|---|
Version: | Boost 1.63.0 → Boost 1.59.0 |
if the compiler supports constexpr, the boost::ratio::num or boost::ratio::den are declared and initialized, but not defined (see the ifdef at line 122 in ratio.hpp). As a consequence, ODR-using num or den will result in an unresolved reference.
Using the attached repro with a compiler which does support constexpr gives me:
$ cd ratiosymbol $ make /usr/lib/ccache/g++ -std=c++11 -c -g -fPIC -I/home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include -o test.o test.cc /usr/lib/ccache/g++ -std=c++11 -o test test.o test.o: In function `main': /home/sbarthelemy/ar/s/ratiosymbol/test.cc:9: undefined reference to `boost::ratio<1l, 1000000000l>::den' /home/sbarthelemy/ar/s/ratiosymbol/test.cc:9: undefined reference to `boost::ratio<1l, 1000000000l>::num' collect2: error: ld returned 1 exit status make: *** [test] Error 1 $ nm test.o |grep ratio | c++filt U boost::ratio<1l, 1000000000l>::den U boost::ratio<1l, 1000000000l>::num $ ${CXX} -v Using built-in specs. COLLECT_GCC=/usr/bin/g++ 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.4-2ubuntu1~14.04.3' --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 --disable-libmudflap --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,mx32 --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.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
I think the proper fix is to remove the #ifdev and thus define num and den whether the compiler supports constexpr or not.
follow-up: 3 comment:2 by , 5 years ago
Ah, glad I'm not the only person experiencing this. gcc and clang C++03 mode => code was fine for years; clang C++11 mode => undefined reference for ratio<>::num and ::den.
Though, I am not totally sure what "ODR-using" is, exactly, nor how to work around this. I'm sure I'll find a way, but this seems like a rather significant link error given the simplicity and thus probable commonness of what is being attempted here. It doesn't seem like the repro (nor my code, not provided here) is doing anything strange.
follow-up: 4 comment:3 by , 5 years ago
Replying to yuri.goldfeld@…:
Ah, glad I'm not the only person experiencing this. gcc and clang C++03 mode => code was fine for years; clang C++11 mode => undefined reference for ratio<>::num and ::den.
Though, I am not totally sure what "ODR-using" is, exactly, nor how to work around this. I'm sure I'll find a way, but this seems like a rather significant link error given the simplicity and thus probable commonness of what is being attempted here. It doesn't seem like the repro (nor my code, not provided here) is doing anything strange.
For the record, *a* work-around I found is to indeed define what appears to be under #ifdef in the ratio.hpp code. Like so, in your .cc or .cpp file:
template <boost::intmax_t N, boost::intmax_t D> const boost::intmax_t boost::ratio<N, D>::num; template <boost::intmax_t N, boost::intmax_t D> const boost::intmax_t boost::ratio<N, D>::den;
That should do it as a work-around. However, presumably it'll break if the compiler lacks constexpr, as it would be a duplicate or something along those lines.
comment:4 by , 5 years ago
Replying to anonymous:
Replying to yuri.goldfeld@…:
Ah, glad I'm not the only person experiencing this. gcc and clang C++03 mode => code was fine for years; clang C++11 mode => undefined reference for ratio<>::num and ::den.
Though, I am not totally sure what "ODR-using" is, exactly, nor how to work around this. I'm sure I'll find a way, but this seems like a rather significant link error given the simplicity and thus probable commonness of what is being attempted here. It doesn't seem like the repro (nor my code, not provided here) is doing anything strange.
For the record, *a* work-around I found is to indeed define what appears to be under #ifdef in the ratio.hpp code. Like so, in your .cc or .cpp file:
template <boost::intmax_t N, boost::intmax_t D> const boost::intmax_t boost::ratio<N, D>::num; template <boost::intmax_t N, boost::intmax_t D> const boost::intmax_t boost::ratio<N, D>::den;
That should do it as a work-around. However, presumably it'll break if the compiler lacks constexpr, as it would be a duplicate or something along those lines.
And of course it can be #ifndef'ed with BOOST_NO_CXX11_CONSTEXPR.
OK, that's enough spam about work-arounds.
simple repro