vector types not friendly to C++ (specifically, std::vector)

Neil Trevett here at the GTC told me to post this here as OpenCL feedback. The following code will not compile on OSX 10.6 with gcc 4.2:

int main(int, char *[])
{
std::vector<cl_float4> foo;

cl_float4 bar = {0.0f, 1.0f, 2.0f, 3.0f};

foo.push_back(bar);

return 0;
}

It throws the following error:
/usr/bin/c++ -g -W -Wall -pedantic -O3 -Wno-long-long -ffast-math -arch x86_64 -msse3 -I…/debug/libs/include_public -I…/debug/libs/include_private -I. -c testFloat4.cpp
/usr/include/c++/4.2.1/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = float [4]]’:
/usr/include/c++/4.2.1/bits/stl_vector.h:604: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
testFloat4.cpp:13: instantiated from here
/usr/include/c++/4.2.1/ext/new_allocator.h:107: error: ISO C++ forbids initialization in array new
/usr/include/c++/4.2.1/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’:
/usr/include/c++/4.2.1/bits/stl_vector.h:608: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
testFloat4.cpp:13: instantiated from here
/usr/include/c++/4.2.1/bits/vector.tcc:252: error: array must be initialized with a brace-enclosed initializer
/usr/include/c++/4.2.1/bits/stl_vector.h:608: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
testFloat4.cpp:13: instantiated from here
/usr/include/c++/4.2.1/bits/vector.tcc:256: error: invalid array assignment
/usr/include/c++/4.2.1/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_backward<_BoolType, std::random_access_iterator_tag>::__copy_b(_BI1, _BI1, _BI2) [with _BI1 = float ()[4], _BI2 = float ()[4], bool _BoolType = false]’:
/usr/include/c++/4.2.1/bits/stl_algobase.h:465: instantiated from ‘_BI2 std::__copy_backward_aux(_BI1, _BI1, _BI2) [with _BI1 = float ()[4], _BI2 = float ()[4]]’
/usr/include/c++/4.2.1/bits/stl_algobase.h:474: instantiated from ‘static _BI2 std::__copy_backward_normal<<anonymous>, <anonymous> >::__copy_b_n(_BI1, _BI1, _BI2) [with _BI1 = float ()[4], _BI2 = float ()[4], bool <anonymous> = false, bool <anonymous> = false]’
/usr/include/c++/4.2.1/bits/stl_algobase.h:540: instantiated from ‘_BI2 std::copy_backward(_BI1, _BI1, _BI2) [with _BI1 = float ()[4], _BI2 = float ()[4]]’
/usr/include/c++/4.2.1/bits/vector.tcc:253: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
/usr/include/c++/4.2.1/bits/stl_vector.h:608: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
testFloat4.cpp:13: instantiated from here
/usr/include/c++/4.2.1/bits/stl_algobase.h:433: error: invalid array assignment
/usr/include/c++/4.2.1/bits/stl_construct.h: In function ‘void std::_Construct(_T1*, const _T2&) [with _T1 = float [4], _T2 = float [4]]’:
/usr/include/c++/4.2.1/bits/stl_uninitialized.h:87: instantiated from ‘_ForwardIterator std::__uninitialized_copy_aux(_InputIterator, _InputIterator, _ForwardIterator, std::__false_type) [with _InputIterator = float ()[4], _ForwardIterator = float ()[4]]’
/usr/include/c++/4.2.1/bits/stl_uninitialized.h:114: instantiated from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = float ()[4], _ForwardIterator = float ()[4]]’
/usr/include/c++/4.2.1/bits/stl_uninitialized.h:254: instantiated from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>) [with _InputIterator = float ()[4], _ForwardIterator = float ()[4], _Tp = float [4]]’
/usr/include/c++/4.2.1/bits/vector.tcc:275: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
/usr/include/c++/4.2.1/bits/stl_vector.h:608: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = float [4], _Alloc = std::allocator<float [4]>]’
testFloat4.cpp:13: instantiated from here
/usr/include/c++/4.2.1/bits/stl_construct.h:81: error: ISO C++ forbids initialization in array new

Basically, cl_float4 is a typedef of float[4]. Which is an array, which doesn’t have operator= defined. This could be avoided if the vector types were defined as structs with members like the following:
typedef struct
{
float x,y,z,w;
] cl_float4;

And then the cl_float4 in host code actually behaves more closely to the device code! So I think it makes sense all around. It does break backward compatibility though, not sure if that is allowable yet.

Thanks,
Brian Cole

Forgot I posted something similar to this before: viewtopic.php?f=28&t=1848

Sorry for the duplication. But the unsuitability of cl_float4 still stands.