我使用gcc 4.8直到我升级Ubuntu,现在我有gcc-4.9.1-16。用于编译而没有警告且运行正常的代码现在不再编译。
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));
最后一行错误
... / foo.cpp:68:62:从这里要求 /usr/include/c++/4.9/bits/stl_algobase.h:373:4:错误:静态断言失败:类型不可分配
... / foo.cpp:68:62:从这里要求 /usr/include/c++/4.9/bits/stl_construct.h:75:7:错误:数组new中的括号初始值设定项[-fpermissive]
编译选项没有改变,只要我知道gcc已经改变,它们就是-W -Wall -Wextra -Werror -pedantic --std=c++0x
。
为什么这段代码不再编译?
答案 0 :(得分:5)
标准容器的值类型的最低要求是它们必须是Erasable
。对于默认分配器,这转换为给定value_type *p;
,p->~value_type();
必须格式正确的要求。
如果value_type
是类类型,它只是调用析构函数,并且如果析构函数未被删除且可访问,则格式良好。如果value_type
表示标量类型,p->~value_type();
也有效且无操作(这称为伪析构函数调用)。但是,如果value_type
是数组类型,则p->~value_type();
无效。
因此,内置数组永远不是标准容器的有效值类型,至少在使用默认分配器时是这样。 (各种其他容器操作对值类型提出了更多要求;内置数组至少会与其中一些相关,因为它们不可分配。)
使用不满足该模板要求的类型实例化标准库模板会导致未定义的行为。看来,偶然的libstdc ++在GCC 4.9附带的版本之前没有诊断出你的错误。
顺便说一下,修复很简单。只需使用std::array
。
答案 1 :(得分:0)
一段时间后,该线程帮助我弄清了这个错误。我不得不使用的一些旧代码也停止了编译,我不知道为什么。我没有注意到我已经在系统升级中更新了编译器版本,而新标准导致了
stl_algobase.h:364:4: error: static assertion failed: type is not assignable
我的解决方案是强制它使用03标准(--std = c ++ 03)而不是新的默认值进行编译。对于那些无法使用适当的std::array
重新编写大量代码的人来说,我将其保留为一个简单的解决方法。