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)

ratiosymbol.tgz (521 bytes ) - added by barthelemy@… 5 years ago.
simple repro

Download all attachments as: .zip

Change History (5)

by barthelemy@…, 5 years ago

Attachment: ratiosymbol.tgz added

simple repro

comment:1 by barthelemy@…, 5 years ago

Summary: undefined symbolundefined reference error when ODR-using boost::ratio::{num,den}
Version: Boost 1.63.0Boost 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.

comment:2 by yuri.goldfeld@…, 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.

in reply to:  2 ; comment:3 by anonymous, 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.

in reply to:  3 comment:4 by yuri.goldfeld@…, 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.

Note: See TracTickets for help on using tickets.