Boost C++ Libraries: Ticket #6331: [Boost.Test] g++ compilation error due to ambiguity between template<class Cond, class T> struct boost::enable_if and class boost::unit_test::decorator::enable_if as well as the disable_if counterparts introduced after Boost 1.48.0 (up to at least svn rev. 76217) https://svn.boost.org/trac10/ticket/6331 <p> The attached test case exposes a compilation problem with g++ (not clang++) against Boost trunk svn rev. &lt;=76217 (after 1.48.0 release) due to an ambiguity between [[[template&lt;class Cond, class T&gt; struct boost::enable_if}}} and <code>class boost::unit_test::decorator::enable_if</code> in <code>boost/typeof/native.hpp</code>, as well as the disable_if counterparts. The test case compiles correctly against Boost 1.48.0 using Apple g++ 4.2.1, <a class="missing wiki">MacPorts</a> g++ 4.5.3 and 4.6.2 as well as Apple clang++ 3.0 on Mac OS X Lion 10.7.2 and Xcode 4.2.1. It fails to compile against Boost trunk until at least svn rev. 76217 using any of the mentioned g++ versions. Surprisingly, clang++ 3.0 is still able to correctly compile the test case. The test case is derived from test_signed_integer_output_with_karma.cpp in Trac ticket <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/6126" title="#6126: Bugs: Signed integer members of Boost.Fusion adapted ADTs are not output ... (closed: fixed)">#6126</a>. During the <a class="ext-link" href="http://sourceforge.net/mailarchive/forum.php?thread_name=CAGCnmH11u2%2Bvfef9v8YpPnbv1cN%3Da5Px2xSu%3DKTnaKBve2vTwQ%40mail.gmail.com&amp;forum_name=spirit-general"><span class="icon">​</span>discussion</a> of ticket <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/6126" title="#6126: Bugs: Signed integer members of Boost.Fusion adapted ADTs are not output ... (closed: fixed)">#6126</a> on the Boost-Spirit-general mailing list, Jeroen Habraken identified the header <code>boost/test/tree/decorator.hpp</code> as the origin for the compilation failure of the test case against Boost trunk. He found the cause to be an ambiguity: </p> <pre class="wiki">$ g++-mp-4.6 -o test_boost_test_decorator_enable_if test_boost_test_decorator_enable_if.cpp -I.../boost-trunk In file included from test_boost_test_decorator_enable_if.cpp:58:0: boost/typeof/native.hpp:30:18: error: expected nested-name-specifier before 'enable_if' boost/typeof/native.hpp:30:27: error: expected initializer before '&lt;' token boost/typeof/native.hpp:34:18: error: expected nested-name-specifier before 'disable_if' boost/typeof/native.hpp:34:28: error: expected initializer before '&lt;' token </pre><p> These occur because the code states "<code>typename enable_if&lt;Cond, T&gt;::type</code>" and the <code>type name</code> doesn't make sense in combination with <code>boost::unit_test::decorator::enable_if</code>. When removing the <code>typename</code>, on gets the following ambiguity error: </p> <pre class="wiki">boost/typeof/native.hpp:30:9: error: reference to 'enable_if' is ambiguous boost/utility/enable_if.hpp:36:10: error: candidates are: template&lt;class Cond, class T&gt; struct boost::enable_if boost/test/tree/decorator.hpp:184:23: error: class boost::unit_test::decorator::enable_if </pre><p> showing the conflict between <code>template&lt;class Cond, class T&gt; struct boost::enable_if</code> and <code>class boost::unit_test::decorator::enable_if</code>. </p> <p> As <code>enable_if</code> is often used without being fully qualified this breaks in a major fashion. Since <code>boost/test/tree/decorator.hpp</code> seems to be quite new (added 2011-10-02 11:00:16 +0200) it might be best fixed there. </p> <p> My search on trac for <code>boost::unit_test::decorator_enable_if</code> turned up <a class="ext-link" href="https://svn.boost.org/trac/boost/changeset/74663"><span class="icon">​</span>changeset 74663</a> by rogeeff, who I therefore put in CC. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6331 Trac 1.4.3 t0rt1e@… Thu, 29 Dec 2011 13:37:10 GMT attachment set https://svn.boost.org/trac10/ticket/6331 https://svn.boost.org/trac10/ticket/6331 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">test_boost_test_decorator_enable_if.cpp</span> </li> </ul> <p> test case </p> Ticket t0rt1e@… Thu, 29 Dec 2011 21:12:42 GMT keywords changed https://svn.boost.org/trac10/ticket/6331#comment:1 https://svn.boost.org/trac10/ticket/6331#comment:1 <ul> <li><strong>keywords</strong> disable_if added </li> </ul> Ticket t0rt1e@… Tue, 17 Jan 2012 17:04:47 GMT severity changed https://svn.boost.org/trac10/ticket/6331#comment:2 https://svn.boost.org/trac10/ticket/6331#comment:2 <ul> <li><strong>severity</strong> <span class="trac-field-old">Problem</span> → <span class="trac-field-new">Regression</span> </li> </ul> Ticket rogeeff@… Wed, 18 Jan 2012 15:22:29 GMT <link>https://svn.boost.org/trac10/ticket/6331#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6331#comment:3</guid> <description> <ol><li>I am yet to see why this is boost.test fault and not compiler bug. </li><li>I think qualifying symbols from boost namespace is right thing to </li></ol><p> do in any case </p> <ol start="3"><li>This code is not part of the release. </li></ol><p> Gennadiy </p> </description> <category>Ticket</category> </item> <item> <author>t0rt1e@…</author> <pubDate>Wed, 18 Jan 2012 15:37:43 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6331#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6331#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/6331#comment:3" title="Comment 3">rogeeff@…</a>: </p> <blockquote class="citation"> <ol><li>I am yet to see why this is boost.test fault and not compiler bug. </li></ol></blockquote> <p> It might well be a compiler bug, but seeing how long it takes that new compiler versions are widely deployed even on common platforms such as Windows, Linux, or Mac OS X -- especially in production environments, such issues should be fixed also in the Boost library. </p> <p> That said, before simply blaming the compiler, we should also make sure that it is not some bug in Boost.Test or other Boost component. </p> <p> The test case just includes two Boost headers and then fails to compile with g++ 4.2.1, 4.5.3, and 4.6.2 (clang+ + 3.0 compiles just fine the test case): </p> <pre class="wiki">#define BOOST_TEST_MODULE test_boost_test_decorator_enable_if #include &lt;boost/test/included/unit_test.hpp&gt; #include &lt;boost/typeof/native.hpp&gt; BOOST_AUTO_TEST_CASE(test_dummy) { // do nothing } </pre><p> I'm not familiar enough with all the magic going on behind the scenes in Boost.Test to judge if it not changes the visibility of certain symbols in certain namespaces, e.g., by issuing <code>using</code> statements. </p> <p> At least, just including into a test case: </p> <pre class="wiki">#include &lt;boost/test/tree/decorator.hpp&gt; #include &lt;boost/typeof/native.hpp&gt; int main(int argc, char* argv[]) { return 0; } </pre><p> won't cause a compiler error. I don't know what triggers the compiler to look-up <code>enable_if&lt;Cond, T&gt;</code> in the other test case. </p> <p> I don't know either why the compiler sees the definition of <code>boost::unit_test::decorator::enable_if</code> in <code>namespace boost::type_of</code>. </p> <p> I don't know how to further analyse the issue. </p> <blockquote class="citation"> <ol start="2"><li>I think qualifying symbols from boost namespace is right thing to do in any case </li></ol></blockquote> <p> Well, I agree, but what is a user of the Boost libraries able to do about it? Using <code>enable_if</code> and co. without a qualifying namespace is widespread in the Boost sources: A grep on the Boost headers and some filtering shows that <code>enable_if</code> without a qualifying namespace identifier is used approx. 1000 times all over the Boost library. Therefore, I can imaging that qualifying all occurences of <code>enable_if</code> and co. will need a quite huge and well coordinated effort to be fixed by the different library authors. </p> <p> I am aware that also other Boost libraries have their own <code>enable_if</code> variants. However, all seem to be templates except for the <code>boost::unit_test::decorator::enable_if</code>. Maybe therefore no problems were yet observed in combination with <code>typename</code> statements. At least that is how far I understand the issue. </p> <blockquote class="citation"> <ol start="3"><li>This code is not part of the release. </li></ol></blockquote> <p> This is good to hear. Boost.Test is very useful for me and I use it in conjunction with other Boost libraries regularly. Having it broken in a an official Boost release would cause me quite some headache as suddenly my unit tests for my own code would stop compiling for reasons I cannot influence. </p> <blockquote class="citation"> <p> Gennadiy </p> </blockquote> </description> <category>Ticket</category> </item> <item> <author>t0rt1e@…</author> <pubDate>Fri, 20 Jan 2012 14:25:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6331#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6331#comment:5</guid> <description> <p> While digging into the issue, I came across the <a class="ext-link" href="http://gcc.gnu.org/gcc-4.7/changes.html"><span class="icon">​</span>CHANGES</a> document for g++ 4.7.0 currently under development. It states: </p> <p> "G++ now correctly implements the two-phase lookup rules such that an unqualified name used in a template must have an appropriate declaration found either in scope at the point of definition of the template or by argument-dependent lookup at the point of instantiation. As a result, code that relies on a second unqualified lookup at the point of instantiation to find functions declared after the template or in dependent bases will be rejected. The compiler will suggest ways to fix affected code, and using the -fpermissive compiler flag will allow the code to compile with a warning." </p> <p> Could this problem be related? </p> <p> I also found a meta-bug in gcc's bug tracker (<a class="ext-link" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18805"><span class="icon">​</span>ticket #18805</a>) grouping currently known problems around the name-lookup. </p> </description> <category>Ticket</category> </item> <item> <author>t0rt1e@…</author> <pubDate>Fri, 20 Jan 2012 14:28:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6331#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6331#comment:6</guid> <description> <p> I just tried to compile the test case with g++ version 4.7.0 20120114 (experimental). It still gives the same errors as the older g++ that I tried previously. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Gennadiy Rozental</dc:creator> <pubDate>Fri, 20 Jan 2012 23:16:23 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/6331#comment:7 https://svn.boost.org/trac10/ticket/6331#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/76600" title="Fixes #6331">[76600]</a>) Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/6331" title="#6331: Bugs: [Boost.Test] g++ compilation error due to ambiguity between ... (closed: fixed)">#6331</a> </p> Ticket t0rt1e@… Sat, 21 Jan 2012 09:36:26 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/6331#comment:8 https://svn.boost.org/trac10/ticket/6331#comment:8 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> Thanks for finding the origin of the issue in a misplaced <code>using namespace boost::unit_test</code> statement in the implementation of the boost::unit_test! Unfortunately, the change set 76600 doesn't fully resolve the issue. There's another <code>using namespace boost::unit_test</code> statement hidden in in <code>boost/test/impl/logged_expectations.ipp</code>. I attach a patch, which finally allows me to compile my test case against Boost trunk. </p> Ticket t0rt1e@… Sat, 21 Jan 2012 09:38:35 GMT attachment set https://svn.boost.org/trac10/ticket/6331 https://svn.boost.org/trac10/ticket/6331 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">test_impl_logged_expectations.ipp.patch</span> </li> </ul> <p> Patch misplaced using namespace statement in boost/test/impl/logged_expectations.ipp </p> Ticket t0rt1e@… Mon, 06 Feb 2012 10:25:28 GMT <link>https://svn.boost.org/trac10/ticket/6331#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6331#comment:9</guid> <description> <p> I just checked out Boost trunk rev. 76906. <code>test_impl_logged_expectations.ipp.patch</code> hasn't been applied to it yet to fix the misplaced <code>using namespace</code> statement in <code>boost/test/impl/logged_expectations.ipp</code>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Gennadiy Rozental</dc:creator> <pubDate>Sun, 04 Nov 2012 20:31:33 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/6331#comment:10 https://svn.boost.org/trac10/ticket/6331#comment:10 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket