I can no longer assign char [M] [N] types to std :: vector on gcc 4.9

I used gcc 4.8 until I updated Ubuntu, now I have gcc-4.9.1-16. The code that was used to compile without warnings and executed normally now no longer compiles.

static const unsigned WIDTH = 16; static const unsigned VSCALE = 1; static const unsigned HEIGHT = WIDTH / VSCALE; static const unsigned FOOTER = 2; typedef char Row [WIDTH + 1]; typedef Row World [HEIGHT - FOOTER]; std :: vector <World> m_levels; World levels [] = { { " ", " ", " ", " ", " ", " ### ### ", " ", "1122112211221122", " 33003300330033 ", "1122112211221122", " 33003300330033 ", " ", " ", " " }, { " 44 ", " 555 55 ", " 66 66 ", " 777 777 ", " 66 66 ", " 777 777 ", " 66# #66 ", " 777 # # 777 ", " 66 # # 66 ", " 777 # # 777 ", " 66# #66 ", " 555 55 ", " 44 ", " " } }; // The next line is line 68 m_levels .assign (std :: begin (levels), std :: end (levels)); 

Final string errors using

... / foo.cpp: 68: 62: required from here / usr / include / c ++ / 4.9 / bits / stl_algobase.h: 373: 4: error: static statement failed: type is not assigned

... / foo.cpp: 68: 62: required from here / usr / include / c ++ / 4.9 / bits / stl_construct.h: 75: 7: error: initializer in brackets in the array new [-fpermissive]

The compilation options have not changed, they are -W -Wall -Wextra -Werror -pedantic --std=c++0x , as far as I can tell, only gcc has changed.

Why is this code no longer compiling?

+5
source share
1 answer

The minimum requirement for value types for standard containers is that they must be Erasable . For a default allocator, this means requiring the data value_type *p; , p->~value_type(); must be well formed.

If value_type is a class type, it simply calls the destructor and is correctly formed if the destructor is not deleted and is inaccessible. If value_type denotes a scalar type, then p->~value_type(); also has a value p->~value_type(); and no-op (this is called a pseudo destructor call). However, if value_type is an array type, then p->~value_type(); is invalid.

Therefore, inline arrays are never valid value types for standard containers, at least when the default allocator is used. (Various other container operations impose more requirements on the type of value, inline arrays will work from at least some of them, since they cannot be assigned.)

Creating a standard library template with types that do not satisfy the requirements of this template leads to undefined behavior. It seems that libstdc ++ bystancestance did not diagnose your error prior to the version shipped with GCC 4.9.

The fix, by the way, is simple. Just use std::array .

+4
source

Source: https://habr.com/ru/post/1210069/


All Articles