GCC允许从函数返回数组 - 错误或功能?

时间:2015-04-14 13:25:12

标签: c++ arrays gcc

我很惊讶地发现GCC允许函数在使用尾随返回类型而不是正常返回类型时返回数组。你可能知道数组不能被复制,所以这是非常有限的但是让我给你看一些很酷的example

#include <iostream>
#include <typeinfo>

using namespace std;

auto func() -> int [5]
{
    return {4, 56, 78, 4, 0};
}

int main()
{
    cout << func()[2] << endl;
    cout << typeid(func).name() << endl;
}

这是编译器错误还是一些新功能?

有趣的是&#39; typeid&#39;返回&#39; FA5_ivE&#39;被解构为&#39; int (()) [5]&#39;这意味着你认为函数返回5个int的数组。

编辑:我尝试将返回的数组绑定到右值引用但没有任何成功(使用大多数可能的形式):

auto &&refArrayTemp{ func() };

似乎这种扩展毫无用处。

2 个答案:

答案 0 :(得分:13)

这是一个bug in gcc(固定as of 2017-07-03),由跟踪返回类型的不一致处理引起。

首先注意两次尝试声明返回函数的函数之间的错误消息的区别:

using Fv = void();
Fv f1();             // error: 'f1' declared as function returning a function
auto f2() -> Fv;     // error: function return type cannot be function

第一个错误来自decl.c,处理声明符,而第二个错误来自tree.c,更深入到内部,尝试构建准备生成代码的函数类型。

尾随返回类型在decl.c 30 lines below中处理上述错误 - 用上面的错误代码捕获它太晚了,并且没有单独处理。

对于数组,类似地使用trailing-return-type允许我们跳过decl.c中的检查,区别在于function-returning-array实际上在gcc的内部表示方面是有效的。

请注意,你不能做太多事情; gcc不允许您分配,引用绑定,衰减或将func()的结果传递给另一个函数:

auto a1 = func();
// error: invalid use of non-lvalue array

auto& a2 = func();
// error: invalid initialization of non-const reference of type 'int (&)[5]' from an rvalue of type 'int [5]'

auto&& a3 = func();
// error: lvalue required as unary '&' operand

的确,即使您的代码在-Wpedantic

被拒绝
warning: ISO C++ forbids subscripting non-lvalue array

最后,通过利用类似的bug(在处理trailing-return-types之前从标量中删除限定符),我们可以创建一个类型为int const volatile()的函数:

int const volatile g1();          // warning: type qualifiers ignored on function return type
auto g2() -> int const volatile;  // OK!!

答案 1 :(得分:8)

最新草案,[dcl.array] / p10:

  

函数不应具有类型数组或函数的返回类型,尽管它们的返回类型可能为   类型指针或对此类事物的引用。虽然可以有数组,但不应有任何函数数组   指向函数的指针。

这可能是非标准的GCC扩展。 It doesn't compile in the trunk version of clang.但是,这可能也是一个错误,因为它与non-trailing return type的行为不一致。