Boost logo

Boost :

Subject: [boost] [BGL] Visual Studio 12 finish_edge() failure, general BOOST_TTI_HAS_MEMBER_FUNCTION failure?
From: Michael Behrns-Miller (m_at_[hidden])
Date: 2014-03-31 13:27:34


Hello boost!

In the BGL, finish_edge() is a visitor function of DFS, but it is
optional. It is made optional via BOOST_TTI_HAS_MEMBER_FUNCTION. Here's
how BGL defines it:

-------------

     BOOST_TTI_HAS_MEMBER_FUNCTION(finish_edge)

     template <bool IsCallable> struct do_call_finish_edge {
       template <typename E, typename G, typename Vis>
       static void call_finish_edge(Vis& vis, const E& e, const G& g) {
         vis.finish_edge(e, g);
       }
     };

     template <> struct do_call_finish_edge<false> {
       template <typename E, typename G, typename Vis>
       static void call_finish_edge(Vis&, const E&, const G&) {}
     };

     template <typename E, typename G, typename Vis>
     void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only
call if method exists
       do_call_finish_edge<has_member_function_finish_edge<Vis,
void>::value>::call_finish_edge(vis, e, g);
     }

-------------

In all my efforts, the Visual Studio 12 compiler fails to call
finish_edge(). I've tried templated versions, direct versions, virtual
versions, with and without const params, inline and not inline. In
every case, VS says "code will not be hit, no executable code is
associated with this line. possible causes: preprocessor directives or
compiler/linker optimizations". I'm in debug mode with minimal
optimizations, and there's no preprocessor wrapper.

It's possible there's a problem with the way I'm calling it, but it
happens when I use a simple example from another user. This ticket
includes very simple sample code that should fire the finish_edge()
function. It does not work for me using VS 12:

https://svn.boost.org/trac/boost/ticket/9770
https://svn.boost.org/trac/boost/attachment/ticket/9770/test.cc

I have a large project depending on the BGL, which has been great
otherwise. I've coded a workaround by using the other non-optional
visitor functions. But there are edge cases (sorry, no pun intended!
ha) that fail with my workaround. The only possible solution is to get
finish_edge() to fire. I'd like to do it the intended way, rather than
rewrite BGL code to make finish_edge() non-optional.

I'll go try this with a recent version of gcc now...

Thanks for any input at all!

Michael Behrns-Miller


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk