Opened 16 years ago

Closed 16 years ago

#854 closed Bugs (None)

multi_index, multi_array collision

Reported by: nobody Owned by: joaquintides
Milestone: Component: multi_index
Version: None Severity:
Keywords: Cc:

Description

I'm not the most experienced user, so pl. excuse me if I'm just missing something.

venkyn@gmail.com

-------test.cc--------

/*
simply including this causes the following errors on compilation
*/
#include <boost/multi_index_container.hpp>

#include <boost/multi_array.hpp>

int main()
{
/* this is one of the examples in the Boost multiarray
documentation
*/
  typedef boost::multi_array<double, 3> array_type;
  array_type A( boost::extents[3][4][2] );
  A[0][0][0] = 3.14;
}

----------
Trying to compile this:

$> /home/sapo/software/compilers/gcc/gcc-3.2.3-install/bin/g++ -I/home/sapo/software/compilers/gcc/gcc-3.2.3-install/include -I/home/sapo/software/boost//include/boost-1_33_1  -L/home/sapo/software/compilers/gcc/gcc-3.2.3-install/lib -lm  -o test src/test.cc
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/multi_array_ref.hpp: In
   member function `boost::const_multi_array_ref<T, NumDims, T*>::reference
   boost::multi_array_ref<T,
   NumDims>::operator[](boost::const_multi_array_ref<T, NumDims, T*>::index)
   [with T = double, unsigned int NumDims = 3]':
src/test.cc:12:   instantiated from here
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/multi_array_ref.hpp:515: no
   matching function for call to `boost::const_multi_array_ref<double, 3,
   double*>::access(boost::type<boost::detail::multi_array::sub_array<double,
   2> >, index&, double*, const size_type*, const index*, const index*)'
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp: In
   member function `boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::reference boost::detail::multi_array::sub_array<T,
   NumDims>::operator[](boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::index) [with T = double, unsigned int NumDims = 2]':
src/test.cc:12:   instantiated from here
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp:261: no
   matching function for call to `
   boost::detail::multi_array::const_sub_array<double, 2, double*>::access(
   boost::type<boost::detail::multi_array::sub_array<double, 1> >, index&,
   double*&, const size_type*, const index*, const index*)'
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp: In
   member function `boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::reference boost::detail::multi_array::sub_array<T,
   NumDims>::operator[](boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::index) [with T = double, unsigned int NumDims = 1]':
src/test.cc:12:   instantiated from here
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp:261: no
   matching function for call to `
   boost::detail::multi_array::const_sub_array<double, 1, double*>::access(
   boost::type<double&>, index&, double*&, const size_type*, const index*,
   const index*)'

Change History (6)

comment:1 by nobody, 16 years ago

Logged In: NO 

I should clarify that it is the 

A[0][0][0] = 3.14

line that gives the compilation errors.

comment:2 by joaquintides, 16 years ago

Logged In: YES 
user_id=911241
Originator: NO

Hello,

I've just tried your snippet in GCC 3.4.4 and it works OK, so the
problem seems to be confined to quite old versions of the
compiler. Can you upgrade? If you can't you might try the
following: replace the five occurrences of

  super_type::replace(...)

at lines 215, 515 and 578 of boost/multi_array/multi_array_ref.hpp
and lines 76 and 261 of of boost/multi_array/subarray.hpp
with:

  this->replace(...)

Does the error vanish? If so, you might want to propose these
changes as a patch to the Boost.MultiArray author.

Hope this helps, please report back,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo

comment:3 by joaquintides, 16 years ago

Logged In: YES 
user_id=911241
Originator: NO

Hello again,

I've gotten access to a GCC 3.2 installation and been investigating
the issue a little more. The problem can also be triggered by the
following snippet:

#include <boost/serialization/access.hpp>
#include <boost/multi_array.hpp>

int main()
{
  typedef boost::multi_array<double, 3> array_type;
  array_type A( boost::extents[3][4][2] );
  A[0][0][0] = 3.14;
}

or even with this:

namespace some_namespace{
class access{};
}

#include <boost/multi_array.hpp>

int main()
{
  typedef boost::multi_array<double, 3> array_type;
  array_type A( boost::extents[3][4][2] );
  A[0][0][0] = 3.14;
}

This is a nasty GCC bug: basically, it chokes on 'access' being
defined as a class somewhere and as a member function in some
other place. I've checked and the hack I proposed in my previous
post does *not* work. But fortunately you've got two options to
solve the problem that I've just confirmed to be operational:

1. If you're not using the serialization capabilities of
Boost.MultiIndex, try globally defining the macro
BOOST_MULTI_INDEX_DISABLE_SERIALIZATION. This has the collateral
effect that <boost/serialization/access.hpp> won't be internally
included by B.MI headers, thus avoding the 'access' name clash.

2. Do the following replacements in
boost/multi_array/multi_array_ref.hpp:
  Line 215:
  <    return super_type::access(boost::type<const_reference>(),
  >    return this->template access<const_reference>(boost::type<const_reference>(),
  Line 515:
  <    return super_type::access(boost::type<reference>(),
  >    return this->template access<reference>(boost::type<reference>(),
  Line 578:
  <    return super_type::access(boost::type<const_reference>(),
  >    return this->template access<const_reference>(boost::type<const_reference>(),
and the following in boost/multi_array/subarray.hpp:
  Line 76:
  <    return super_type::access(boost::type<const_reference>(),
  >    return this->template access<const_reference>(boost::type<const_reference>(),
  Line 261:
  <    return super_type::access(boost::type<reference>(),
  >    return this->template access<reference>(boost::type<reference>(),

Either method will do. As for the convenience of applying the
changes in #2 to the CVS version of Boost.MultiArray, my
opinion is that this is not suitable for the official version
of the lib because

a) the offending compiler is quite old;
b) the error conditions are so general that to be perfectly
safe one would have to protect the code against many other possible
name clashes apart from 'access' --basically, the compiler
seems to be too broken. For instance, the following snippet hits
the same problem with a different symbol 'access_element':

namespace some_namespace{
class access_element{};
}

#include <boost/multi_array.hpp>

int main()
{
  typedef boost::multi_array<double, 3> array_type;
  array_type A( boost::extents[3][4][2] );
  boost::array<array_type::index,3> idx = {{0,0,0}};
  A(idx) = 3.14;
}

Hope this helps. Please report back,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo

comment:4 by nobody, 16 years ago

Logged In: NO 

Thanks for the qiuck response, joaquintides!

Unfortunately, I don't think your suggestion fixed it for me:
> /home/sapo/software/compilers/gcc/gcc-3.2.3-install/bin/g++ -I/home/sapo/software/compilers/gcc/gcc-3.2.3-install/include -I/home/sapo/software/boost//include/boost-1_33_1  -L/home/sapo/software/compilers/gcc/gcc-3.2.3-install/lib -lm  -o test src/test.cc
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/multi_array_ref.hpp: In
   member function `boost::const_multi_array_ref<T, NumDims, T*>::reference
   boost::multi_array_ref<T,
   NumDims>::operator[](boost::const_multi_array_ref<T, NumDims, T*>::index)
   [with T = double, unsigned int NumDims = 3]':
src/test.cc:12:   instantiated from here
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/multi_array_ref.hpp:515: no
   matching function for call to `boost::multi_array_ref<double, 3>::access(
   boost::type<boost::detail::multi_array::sub_array<double, 2> >, index&,
   double*, const size_type*, const index*, const index*)'
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp: In
   member function `boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::reference boost::detail::multi_array::sub_array<T,
   NumDims>::operator[](boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::index) [with T = double, unsigned int NumDims = 2]':
src/test.cc:12:   instantiated from here
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp:261: no
   matching function for call to `boost::detail::multi_array::sub_array<double,
   2>::access(boost::type<boost::detail::multi_array::sub_array<double, 1> >,
   index&, double*&, const size_type*, const index*, const index*)'
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp: In
   member function `boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::reference boost::detail::multi_array::sub_array<T,
   NumDims>::operator[](boost::detail::multi_array::const_sub_array<T, NumDims,
   T*>::index) [with T = double, unsigned int NumDims = 1]':
src/test.cc:12:   instantiated from here
/home/sapo/software/boost/include/boost-1_33_1/boost/multi_array/subarray.hpp:261: no
   matching function for call to `boost::detail::multi_array::sub_array<double,
   1>::access(boost::type<double&>, index&, double*&, const size_type*, const
   index*, const index*)'

I can work around it for now. I guess I should pass this report on to Boost.MultiArray.

Thanks again.

comment:5 by nobody, 16 years ago

Logged In: NO 

Ah, I didn't see your second comment when I replied. I'll try your suggestions -- and eventually upgrade the compiler on this machine. Thanks.

comment:6 by joaquintides, 16 years ago

Status: assignedclosed
Note: See TracTickets for help on using tickets.