CGAL fails to compile intersection code only in debug mode.

Alec Jacobson

April 28, 2015

weblog/

I tried to compile:

#include <CGAL/assertions.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/intersections.h>

typedef CGAL::Epeck Kernel;
typedef Kernel::FT CGALScalar;
typedef CGAL::Triangle_3<Kernel> Triangle_3; 

int main(int argc, char * argv[])
{
  Triangle_3 A,B;
  CGAL::do_intersect(A,B);
  CGAL::intersection(A,B);
}

But got stream of CGAL template error diarrhea:


In file included from ./bar.cpp.cpp:44:
In file included from /opt/local/include/CGAL/Exact_predicates_exact_constructions_kernel.h:28:
In file included from /opt/local/include/CGAL/Simple_cartesian.h:28:
In file included from /opt/local/include/CGAL/Cartesian/Cartesian_base.h:68:
In file included from /opt/local/include/CGAL/Cartesian/function_objects.h:28:
In file included from /opt/local/include/CGAL/Kernel/function_objects.h:34:
In file included from /opt/local/include/CGAL/intersection_3.h:34:
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:72:7: error: no matching function for call to 'possibly'
      CGAL_kernel_assertion(obj);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/include/CGAL/kernel_assertions.h:50:5: note: expanded from macro 'CGAL_kernel_assertion'
   (CGAL::possibly(EX)?(static_cast<void>(0)): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__))
    ^~~~~~~~~~~~~~
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:108:3: note: in instantiation of function template
      specialization
      'CGAL::internal::intersection_coplanar_triangles_cutoff<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >'
      requested here
  intersection_coplanar_triangles_cutoff(p,q,r,k,inter_pts); //line pq
  ^
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:190:12: note: in instantiation of function template
      specialization 'CGAL::internal::intersection_coplanar_triangles<CGAL::Simple_cartesian<CGAL::Interval_nt<false> >
      >' requested here
    return intersection_coplanar_triangles(t1,t2,k);
           ^
/opt/local/include/CGAL/Kernel/function_objects.h:2577:24: note: in instantiation of function template specialization
      'CGAL::internal::intersection<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >' requested here
    { return internal::intersection(t1, t2, K() ); }
                       ^
/opt/local/include/CGAL/Lazy.h:440:31: note: in instantiation of function template specialization
      'CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> >
      >::operator()<CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > > >' requested here
BOOST_PP_REPEAT_FROM_TO(2, 9, CGAL_LAZY_REP, _)
                              ^
/opt/local/include/boost/preprocessor/repetition/repeat_from_to.hpp:36:125: note: expanded from macro
      'BOOST_PP_REPEAT_FROM_TO_1'
  ...l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_1(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt)
                                                                                           ^
/opt/local/include/boost/preprocessor/repetition/repeat_from_to.hpp:54:136: note: expanded from macro
      'BOOST_PP_REPEAT_FROM_TO_D_1'
  ...f, l, m, dt) BOOST_PP_REPEAT_1(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_1, (d, f, m, dt))
                                                                                                 ^
/opt/local/include/boost/preprocessor/repetition/repeat.hpp:38:63: note: expanded from macro 'BOOST_PP_REPEAT_1'
# define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d)
                                                              ^
note: (skipping 11 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/opt/local/include/boost/preprocessor/repetition/repeat_from_to.hpp:79:118: note: expanded from macro
      'BOOST_PP_REPEAT_FROM_TO_M_1_I'
  ...n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_1_II(z, BOOST_PP_ADD_D(d, n, f), m, dt)
                                                                                ^
/opt/local/include/boost/preprocessor/repetition/repeat_from_to.hpp:83:54: note: expanded from macro
      'BOOST_PP_REPEAT_FROM_TO_M_1_II'
# define BOOST_PP_REPEAT_FROM_TO_M_1_II(z, n, m, dt) m(z, n, dt)
                                                     ^
/opt/local/include/CGAL/Lazy.h:434:29: note: expanded from macro 'CGAL_LAZY_REP'
    : Lazy_rep<AT, ET, E2A>(ac( BOOST_PP_ENUM(n, CGAL_LN, CGAL::approx) )), BOOST_PP_ENUM(n, CGAL_LINIT, _) \
                            ^
/opt/local/include/CGAL/Lazy.h:1552:39: note: in instantiation of member function
      'CGAL::Lazy_rep_2<boost::optional<boost::variant<CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> >
      >, CGAL::Segment_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      std::__1::vector<CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      std::__1::allocator<CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > > > >,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_> >, boost::optional<boost::variant<CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq>
      >, CGAL::Segment_3<CGAL::Simple_cartesian<CGAL::Gmpq> >, CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> >,
      std::__1::vector<CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq> >,
      std::__1::allocator<CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq> > > >, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_,
      boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> >,
      CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq> >,
      CGAL::Cartesian_converter<CGAL::Simple_cartesian<CGAL::Gmpq>, CGAL::Simple_cartesian<CGAL::Interval_nt<false> >,
      CGAL::NT_converter<CGAL::Gmpq, CGAL::Interval_nt<false> > >, CGAL::Triangle_3<CGAL::Epeck>,
      CGAL::Triangle_3<CGAL::Epeck> >::Lazy_rep_2' requested here
      Lazy<AT, ET, EFT, E2A> lazy(new Lazy_rep_2<AT, ET, AC, EC, E2A, L1, L2>(AC(), EC(), l1, l2));
                                      ^
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:230:1: note: in instantiation of function template
      specialization 'CGAL::Lazy_construction_variant<CGAL::Epeck,
      CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq> >
      >::operator()<CGAL::Triangle_3<CGAL::Epeck>, CGAL::Triangle_3<CGAL::Epeck> >' requested here
CGAL_INTERSECTION_FUNCTION_SELF(Triangle_3, 3)
^
/opt/local/include/CGAL/Intersection_traits.h:88:25: note: expanded from macro 'CGAL_INTERSECTION_FUNCTION_SELF'
    return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \
                        ^
/opt/local/include/boost/preprocessor/cat.hpp:22:47: note: expanded from macro 'BOOST_PP_CAT'
#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
                                              ^
/opt/local/include/boost/preprocessor/cat.hpp:29:34: note: expanded from macro 'BOOST_PP_CAT_I'
#    define BOOST_PP_CAT_I(a, b) a ## b
                                 ^
./bar.cpp.cpp:56:9: note: in instantiation of function template specialization 'CGAL::intersection<CGAL::Epeck>'
      requested here
  CGAL::intersection(A,B);
        ^
/opt/local/include/CGAL/Uncertain.h:263:13: note: candidate function not viable: no known conversion from 'typename
      Intersection_traits<Simple_cartesian<Interval_nt<false> >, typename Simple_cartesian<Interval_nt<false>
      >::Line_3, typename Simple_cartesian<Interval_nt<false> >::Line_3>::result_type' (aka 'optional<variant_type>')
      to 'bool' for 1st argument
inline bool possibly(bool b) { return b; }
            ^
/opt/local/include/CGAL/Uncertain.h:275:6: note: candidate function not viable: no known conversion from 'typename
      Intersection_traits<Simple_cartesian<Interval_nt<false> >, typename Simple_cartesian<Interval_nt<false>
      >::Line_3, typename Simple_cartesian<Interval_nt<false> >::Line_3>::result_type' (aka 'optional<variant_type>')
      to 'Uncertain<bool>' for 1st argument
bool possibly(Uncertain<bool> c)
     ^
In file included from ./bar.cpp.cpp:44:
In file included from /opt/local/include/CGAL/Exact_predicates_exact_constructions_kernel.h:28:
In file included from /opt/local/include/CGAL/Simple_cartesian.h:28:
In file included from /opt/local/include/CGAL/Cartesian/Cartesian_base.h:68:
In file included from /opt/local/include/CGAL/Cartesian/function_objects.h:28:
In file included from /opt/local/include/CGAL/Kernel/function_objects.h:34:
In file included from /opt/local/include/CGAL/intersection_3.h:34:
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:72:7: error: no matching function for call to 'possibly'
      CGAL_kernel_assertion(obj);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/include/CGAL/kernel_assertions.h:50:5: note: expanded from macro 'CGAL_kernel_assertion'
   (CGAL::possibly(EX)?(static_cast<void>(0)): ::CGAL::assertion_fail( # EX , __FILE__, __LINE__))
    ^~~~~~~~~~~~~~
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:108:3: note: in instantiation of function template
      specialization 'CGAL::internal::intersection_coplanar_triangles_cutoff<CGAL::Simple_cartesian<CGAL::Gmpq> >'
      requested here
  intersection_coplanar_triangles_cutoff(p,q,r,k,inter_pts); //line pq
  ^
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:190:12: note: in instantiation of function template
      specialization 'CGAL::internal::intersection_coplanar_triangles<CGAL::Simple_cartesian<CGAL::Gmpq> >' requested
      here
    return intersection_coplanar_triangles(t1,t2,k);
           ^
/opt/local/include/CGAL/Kernel/function_objects.h:2577:24: note: in instantiation of function template specialization
      'CGAL::internal::intersection<CGAL::Simple_cartesian<CGAL::Gmpq> >' requested here
    { return internal::intersection(t1, t2, K() ); }
                       ^
/opt/local/include/CGAL/Lazy.h:1573:20: note: in instantiation of function template specialization
      'CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq>
      >::operator()<CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> >,
      CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> > >' requested here
      ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2));
                   ^
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:230:1: note: in instantiation of function template
      specialization 'CGAL::Lazy_construction_variant<CGAL::Epeck,
      CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >,
      CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq> >
      >::operator()<CGAL::Triangle_3<CGAL::Epeck>, CGAL::Triangle_3<CGAL::Epeck> >' requested here
CGAL_INTERSECTION_FUNCTION_SELF(Triangle_3, 3)
^
/opt/local/include/CGAL/Intersection_traits.h:88:25: note: expanded from macro 'CGAL_INTERSECTION_FUNCTION_SELF'
    return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \
                        ^
/opt/local/include/boost/preprocessor/cat.hpp:22:47: note: expanded from macro 'BOOST_PP_CAT'
#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
                                              ^
/opt/local/include/boost/preprocessor/cat.hpp:29:34: note: expanded from macro 'BOOST_PP_CAT_I'
#    define BOOST_PP_CAT_I(a, b) a ## b
                                 ^
./bar.cpp.cpp:56:9: note: in instantiation of function template specialization 'CGAL::intersection<CGAL::Epeck>'
      requested here
  CGAL::intersection(A,B);
        ^
/opt/local/include/CGAL/Uncertain.h:263:13: note: candidate function not viable: no known conversion from 'typename
      Intersection_traits<Simple_cartesian<Gmpq>, typename Simple_cartesian<Gmpq>::Line_3, typename
      Simple_cartesian<Gmpq>::Line_3>::result_type' (aka 'optional<variant_type>') to 'bool' for 1st argument
inline bool possibly(bool b) { return b; }
            ^
/opt/local/include/CGAL/Uncertain.h:275:6: note: candidate function not viable: no known conversion from 'typename
      Intersection_traits<Simple_cartesian<Gmpq>, typename Simple_cartesian<Gmpq>::Line_3, typename
      Simple_cartesian<Gmpq>::Line_3>::result_type' (aka 'optional<variant_type>') to 'Uncertain<bool>' for 1st
      argument
bool possibly(Uncertain<bool> c)

Compiling with either -DNDEBUG -DCGAL_NDEBUG hides these errors. After a lot of digging, I found a small note in the CGAL doc:

The CGAL::intersection() function used to return an Object, but starting with CGAL 4.2 the return type is determined by a metafunction defined by the kernel. To preserve backward compatibility Object can be constructed from the new return types implicitly, but switching to the new style is recommended. To enable the old style without any overhead, the macro CGAL_INTERSECTION_VERSION must be defined to 1 before any CGAL header is included.

Indeed adding

#define CGAL_INTERSECTION_VERSION 1

Fixes these errors. The doc is pretty confusing and this example is riddled with errors. Just adding auto result = in front of CGAL::intersection(A,B); doesn't make the errors above go away.

Update: This will also avoid the problem above:

#define CGAL_KERNEL_NO_ASSERTIONS