In gcc 4.8.0, the following program fails horribly: #include <vector> int main () { std::vector<volatile int> memory(123); } Change the 'int' to void *' and it works. It fails under OpenSUSE 11.4 and OpenSUSE 12.1, both on AMD 64-bit, and with gcc 4.6.2 as well. The messages are: Test.cpp: In constructor 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = volatile int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<volatile int>]': Test.cpp:4:41: error: could not convert '0' from 'int' to 'const volatile value_type& {aka const volatile int&}' std::vector<volatile int> memory(123); ^ Test.cpp: In function 'int main()': Test.cpp:4:41: error: invalid initialization of reference of type 'const volatile value_type& {aka const volatile int&}' from expression of type 'int' In file included from /home/nmm/GCC/include/c++/4.8.0/vector:65:0, from Test.cpp:1: /home/nmm/GCC/include/c++/4.8.0/bits/stl_vector.h:296:7: error: in passing argument 2 of 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = volatile int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<volatile int>]' vector(size_type __n, const value_type& __value = value_type(), ^ In file included from /home/nmm/GCC/include/c++/4.8.0/x86_64-unknown-linux-gnu/bits/c++allocator.h:33:0, from /home/nmm/GCC/include/c++/4.8.0/bits/allocator.h:47, from /home/nmm/GCC/include/c++/4.8.0/vector:62, from Test.cpp:1: /home/nmm/GCC/include/c++/4.8.0/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::deallocate(__gnu_cxx::new_allocator<_Tp>::pointer, __gnu_cxx::new_allocator<_Tp>::size_type) [with _Tp = volatile int; __gnu_cxx::new_allocator<_Tp>::pointer = volatile int*; __gnu_cxx::new_allocator<_Tp>::size_type = long unsigned int]': /home/nmm/GCC/include/c++/4.8.0/bits/stl_vector.h:175:4: required from 'void std::_Vector_base<_Tp, _Alloc>::_M_deallocate(std::_Vector_base<_Tp, _Alloc>::pointer, std::size_t) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::_Vector_base<_Tp, _Alloc>::pointer = volatile int*; std::size_t = long unsigned int]' /home/nmm/GCC/include/c++/4.8.0/bits/stl_vector.h:162:33: required from 'std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = volatile int; _Alloc = std::allocator<volatile int>]' /home/nmm/GCC/include/c++/4.8.0/bits/stl_vector.h:298:23: required from 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = volatile int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<volatile int>]' Test.cpp:4:41: required from here /home/nmm/GCC/include/c++/4.8.0/ext/new_allocator.h:110:30: error: invalid conversion from 'volatile void*' to 'void*' [-fpermissive] { ::operator delete(__p); } ^ In file included from /home/nmm/GCC/include/c++/4.8.0/ext/new_allocator.h:33:0, from /home/nmm/GCC/include/c++/4.8.0/x86_64-unknown-linux-gnu/bits/c++allocator.h:33, from /home/nmm/GCC/include/c++/4.8.0/bits/allocator.h:47, from /home/nmm/GCC/include/c++/4.8.0/vector:62, from Test.cpp:1: /home/nmm/GCC/include/c++/4.8.0/new:97:6: error: initializing argument 1 of 'void operator delete(void*)' [-fpermissive] void operator delete(void*) _GLIBCXX_USE_NOEXCEPT ^
Well volatile void * is a pointer to volatile void and the pointer itself does not have the volatile on it. I think the only real issue here is the error message. IIRC allocators do not (and cannot) support volatile qualified types.
On May 24 2013, pinskia at gcc dot gnu.org wrote: >http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57403 > > --- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Well > volatile void * is a pointer to volatile void and the pointer itself does > not have the volatile on it. Aargh! Even after all this time, I still fall into that one :-( Yes, you are quite right, and I was making a stupid error. > I think the only real issue here is the error message. IIRC allocators do > not (and cannot) support volatile qualified types. That may well be true, but I can't find any such restriction in the C++ standard. It would be a great help if the library specification weren't so ambiguous - in this case, it hinges around the meaning of the word 'type', and the unqualified word is used with at least three meanings in the standard.
(In reply to Nick Maclaren from comment #2) > That may well be true, but I can't find any such restriction in the C++ > standard. It would be a great help if the library specification weren't > so ambiguous - in this case, it hinges around the meaning of the word > 'type', and the unqualified word is used with at least three meanings > in the standard. C++03 gives the prototype of the constructor: explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator()); which shows that it can't work: typedef volatile int T; void f () { T const& a = T(); } For C++11, the prototype changed, it gets harder to follow...
(In reply to Nick Maclaren from comment #2) > That may well be true, but I can't find any such restriction in the C++ > standard. It would be a great help if the library specification weren't > so ambiguous - in this case, it hinges around the meaning of the word > 'type', and the unqualified word is used with at least three meanings > in the standard. Actually there is a miss in Table 27, where the variables T, U, and C are described as "any non-const object type (3.9)" This should be corrected to "any non-const non-volatile object type (3.9)" I'm submitting an LWG issue for this.
Because of the last comment, I am not going to close this as resolved, invalid, but please do so if appropriate.
The standard containers don't support volatile types.