Boost C++ Libraries: Ticket #13191: undefined reference error when ODR-using boost::ratio::{num,den} https://svn.boost.org/trac10/ticket/13191 en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13191 Trac 1.4.3 barthelemy@… Tue, 05 Sep 2017 08:52:12 GMT attachment set https://svn.boost.org/trac10/ticket/13191 https://svn.boost.org/trac10/ticket/13191 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">ratiosymbol.tgz</span> </li> </ul> <p> simple repro </p> Ticket barthelemy@… Tue, 05 Sep 2017 09:12:13 GMT version, summary changed https://svn.boost.org/trac10/ticket/13191#comment:1 https://svn.boost.org/trac10/ticket/13191#comment:1 <ul> <li><strong>version</strong> <span class="trac-field-old">Boost 1.63.0</span> → <span class="trac-field-new">Boost 1.59.0</span> </li> <li><strong>summary</strong> <span class="trac-field-old">undefined symbol</span> → <span class="trac-field-new">undefined reference error when ODR-using boost::ratio::{num,den}</span> </li> </ul> <p> 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. </p> <p> Using the attached repro with a compiler which does support constexpr gives me: </p> <pre class="wiki">$ 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&lt;1l, 1000000000l&gt;::den' /home/sbarthelemy/ar/s/ratiosymbol/test.cc:9: undefined reference to `boost::ratio&lt;1l, 1000000000l&gt;::num' collect2: error: ld returned 1 exit status make: *** [test] Error 1 $ nm test.o |grep ratio | c++filt U boost::ratio&lt;1l, 1000000000l&gt;::den U boost::ratio&lt;1l, 1000000000l&gt;::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) </pre><p> I think the proper fix is to remove the #ifdev and thus define num and den whether the compiler supports constexpr or not. </p> Ticket yuri.goldfeld@… Wed, 01 Nov 2017 23:03:20 GMT <link>https://svn.boost.org/trac10/ticket/13191#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13191#comment:2</guid> <description> <p> Ah, glad I'm not the only person experiencing this. gcc and clang C++03 mode =&gt; code was fine for years; clang C++11 mode =&gt; undefined reference for ratio&lt;&gt;::num and ::den. </p> <p> 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. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 01 Nov 2017 23:34:19 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13191#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13191#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/13191#comment:2" title="Comment 2">yuri.goldfeld@…</a>: </p> <blockquote class="citation"> <p> Ah, glad I'm not the only person experiencing this. gcc and clang C++03 mode =&gt; code was fine for years; clang C++11 mode =&gt; undefined reference for ratio&lt;&gt;::num and ::den. </p> <p> 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. </p> </blockquote> <p> 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: </p> <p> template &lt;boost::intmax_t N, boost::intmax_t D&gt; const boost::intmax_t boost::ratio&lt;N, D&gt;::num; template &lt;boost::intmax_t N, boost::intmax_t D&gt; const boost::intmax_t boost::ratio&lt;N, D&gt;::den; </p> <p> 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. </p> </description> <category>Ticket</category> </item> <item> <author>yuri.goldfeld@…</author> <pubDate>Fri, 03 Nov 2017 05:30:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13191#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13191#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/13191#comment:3" title="Comment 3">anonymous</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/13191#comment:2" title="Comment 2">yuri.goldfeld@…</a>: </p> <blockquote class="citation"> <p> Ah, glad I'm not the only person experiencing this. gcc and clang C++03 mode =&gt; code was fine for years; clang C++11 mode =&gt; undefined reference for ratio&lt;&gt;::num and ::den. </p> <p> 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. </p> </blockquote> <p> 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: </p> <p> template &lt;boost::intmax_t N, boost::intmax_t D&gt; const boost::intmax_t boost::ratio&lt;N, D&gt;::num; template &lt;boost::intmax_t N, boost::intmax_t D&gt; const boost::intmax_t boost::ratio&lt;N, D&gt;::den; </p> <p> 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. </p> </blockquote> <p> And of course it can be #ifndef'ed with BOOST_NO_CXX11_CONSTEXPR. </p> <p> OK, that's enough spam about work-arounds. </p> </description> <category>Ticket</category> </item> </channel> </rss>