Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
2466 Discussions

Build problem using scalable_allocators in VS2005

mdprice
Beginner
329 Views
I'm having trouble when I declare the key type to be const. This works fine for the standard allocator but gives some funny errors with the scalable_allocator. Here's a sample program that fails to compile:

#include
#include
#include
using namespace std;

int main()
{
typedef int Key;
typedef int Val;

map, allocator > > foo1;
map, tbb::scalable_allocator > > foo2;

typedef const Key cKey;
map, allocator > > foobar1;
map, tbb::scalable_allocator > > foobar2;

return 0;
}

And here is the error:
1>C:\aviews\mprice_quantlib_dev\3rdParty\intel_tbb\tbb21_20080605oss\include\tbb/scalable_allocator.h(87) : error C2535: 'const int *tbb::scalable_allocator::address(const int &) const' : member function already defined or declared
1> with
1> [
1> T=const int
1> ]
1> C:\aviews\mprice_quantlib_dev\3rdParty\intel_tbb\tbb21_20080605oss\include\tbb/scalable_allocator.h(86) : see declaration of 'tbb::scalable_allocator::address'
1> with
1> [
1> T=const int
1> ]
1> C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\xtree(135) : see reference to class template instantiation 'tbb::scalable_allocator' being compiled
1> with
1> [
1> T=const int
1> ]
1> C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\map(82) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
1> with
1> [
1> _Traits=std::_Tmap_traits,tbb::scalable_allocator<:PAIR>>,false>
1> ]
1> .\main.cpp(16) : see reference to class template instantiation 'std::map<_Kty,_Ty,_Pr,_Alloc>' being compiled
1> with
1> [
1> _Kty=cKey,
1> _Ty=Val,
1> _Pr=std::less,
1> _Alloc=tbb::scalable_allocator<:PAIR>>
1> ]


It is somehow getting confused by the following code in scalable_allocator.h:

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

Now for comparison there is appearently similar code in the std implementation:

pointer address(reference _Val) const
{ // return address of mutable _Val
return (&_Val);
}

const_pointer address(const_reference _Val) const
{ // return address of nonmutable _Val
return (&_Val);
}
0 Kudos
2 Replies
ARCH_R_Intel
Employee
329 Views
I can duplicate the problem. I'll post something once I understand the root cause.

0 Kudos
ARCH_R_Intel
Employee
329 Views

I've tracked down the cause: Microsoft's implementation of map does not work with an ISO standard-conforming allocator. Microsoft's std::map depends upon a non-standard extension where allocator strips the constness from T.

Clearly on Windows we should "do as the Romans do", even if its not standard conforming, so that our allocators can be used with Microsoft's containers. The remaining question is how to behave when not in Rome -- specifically whether allocators should strip constness on all platforms.

I can see arguments both ways:
  1. Uniform behavior of the TBB allocators is desirable for portability. That argues for implementing the extension on all platforms.
  2. Uniform behavior of allocators on a platform is desirable for "least surprise" on a platform. For example, non-standard stripping of constness can hide errors in container implementations where the container should have stripped the const.
I'll gather opinions from the TBB team on which way to go on this. Anyone reading this should feel free to chime in with their opinion. I'll post the patch when I have it. As general policy, I'm working on extending our unit tests to catch the problem before I fix it.
0 Kudos
Reply