首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >g++4.9允许std::vector<C_中的错误

g++4.9允许std::vector<C_中的错误
EN

Stack Overflow用户
提问于 2014-08-03 21:01:35
回答 1查看 429关注 0票数 7

考虑以下代码:

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <array>

using namespace std;

typedef double (C_array)[10];

int main()
{ 
    std::vector<C_array> arr(10);

    // let's 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;
    }
}

我刚刚从@juanchopanza https://stackoverflow.com/a/25108679/3093378中发现,这段代码不应该合法,因为一个普通的C-style数组是不可分配/可复制/可移动的。然而,g++在代码中快速运行,即使使用了-Wall -Wextra -pedanticclang++不编译它。当然,如果我尝试执行类似auto arr1 = arr;的操作,它在g++下就会失败,因为它不知道如何将arr复制到arr1中。

我在OS小牛下使用了来自macportsmacports。这里的实时代码:http://goo.gl/97koLa

我的问题是:

  1. 按照标准,这个代码是非法的吗?
  2. g++有那么多才多艺吗?我一直在寻找许多简单的例子,在这些例子中,g++盲目地编译非法代码,上一次是昨天的user-defined conversion operators precedence, compiles in g++ but not clang++,没有太多的努力,只是为了好玩而尝试C++
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-20 16:53:37

您的代码无效C++03。首先,头<array>不是C++03标准库的一部分,但这里也不需要它。第二,向量对象的构造试图调用构造函数。

代码语言:javascript
复制
explicit vector(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());

但是,val的初始化失败的原因与不能编写

代码语言:javascript
复制
C_array foo = C_array();

据我所知,C++03标准第5.2.3节第2段只允许对非数组类型使用这种表示法:

表达式T(),其中T是非数组完整对象类型的简单类型说明符(7.1.5.2)或(可能是cv限定的)空类型,它创建指定类型的rvalue,即值初始化(8.5;不对void()情况进行初始化)。

此外,g++-4.9.0也拒绝编译代码,除非在命令行上提供了-std=c++11:

代码语言:javascript
复制
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);
...

对于C++11,向量容器提供了一个额外的填充构造函数:

代码语言:javascript
复制
explicit vector (size_type n);

这个构造函数要求模板类型是默认的-可构造的(参见23.3.6.2节)。据我所知,这个要求在C++11中也没有得到满足(参见17.6.3.1节),因为为了满足这一要求,表达式C_array()必须创建一个临时对象,这在C++11中也是无效的(同样参见5.2.3节)。我不知道标准是否实际上要求编译器拒绝代码,或者如果没有满足其中一个要求,编译器是否允许编译它,但是标准库的实现只是不需要它。也许对C++11了解更多的人可以填补这里的空白。

除此之外,在我看来,尝试使用数组作为容器元素类型并不是一个好主意,因为其他容器需求没有得到满足。例如,C_array不是可复制的,因此不能复制向量。

关于你的第二个问题:请随意浏览https://gcc.gnu.org/bugzilla/的gcc bugzilla数据库。但是,接受无效代码也可能是故意的,例如,为了不破坏遗留代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25109064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档