G ++ 4.9 error resolving std :: vector <C_type_array>

Consider the following code:

#include <iostream> #include <vector> #include <array> using namespace std; typedef double (C_array)[10]; int main() { std::vector<C_array> arr(10); // let initialize it for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++) arr[i][j] = -1; // now make sure we did the right thing for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { cout << arr[i][j] << " "; } cout << endl; } } 

I just found out from @juanchopanza https://stackoverflow.com/a/167443/ ... that this code should not be legal, since a plain old C style array cannot be assignable / copyable / movable. However, g++ flies through the code, even with -Wall -Wextra -pedantic . clang++ will not compile it. Of course, if I try to do something like auto arr1 = arr; , it fails under g++ since it does not know how to copy arr to arr1 .

I used g++4.9 from macports under OS X Mavericks. Live code here: http://goo.gl/97koLa

My questions:

  • Is this code illegal according to the standard?
  • Is g++ bug? I continue to find many simple examples in which g++ blindly compiles illegal code, the latter was yesterday the priority of user-defined statements, compiled in g ++, but not clang ++ , and without too much effort, just experimenting with C++ for fun.
+7
c ++ c ++ 11 stl
source share
1 answer

Your code is invalid C ++ 03. First, the <array> header is not part of the C ++ 03 standard library, but it is not needed here either. Secondly, the construction of the vector object is trying to call the constructor

 explicit vector(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); 

However, val initialization fails for the same reason you cannot write

 C_array foo = C_array(); 

As far as I understand, paragraph 2 in section 5.2.3 of the C ++ 03 standard allows this designation only for types without an array:

The expression T (), where T is a specifier of a simple type (7.1.5.2) for an object type without an array or a type (void cv-qualified) void, creates an rvalue of the specified type, which is initialized with the value (8.5; initialization is not performed for the case of void () )

In addition, g ++ - 4.9.0 also refuses to compile code if -std = C ++ 11 is not specified on the command line:

 foo.cpp: In constructor 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = double [10]; _Alloc = std::allocator<double [10]>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = double [10]; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<double [10]>]': foo.cpp:11:32: error: functional cast to array type 'std::vector<double [10]>::value_type {aka double [10]}' std::vector<C_array> arr(10); ... 

As for C ++ 11, the vector container offers an additional fill constructor:

 explicit vector (size_type n); 

This constructor requires the template type to be constructive by default (see section 23.3.6.2). As far as I understand, this requirement is also not fulfilled in C ++ 11 (see Section 17.6.3.1), since in order to satisfy the requirement, the expression C_array () must create a temporary object that is also invalid in C ++ 11 (see Section again 5.2.3). I don’t know if the standard really requires the compiler to reject the code, or if the compiler is allowed to compile it if one of the requirements is not met, but he just doesn’t need the standard library implementation. Perhaps people who know more about C ++ 11 can fill in the blanks here.

In addition to all this, in my opinion, it is not recommended to try to use the array as a type of container element, since other requirements for the container are not met. For example, C_array is not copied and, therefore, the vector cannot be copied.

Regarding your second question: Feel free to browse the gcc bugzilla database at https://gcc.gnu.org/bugzilla/ . However, accepting invalid code can also be intentional, for example. so as not to violate outdated code.

+2
source share

All Articles