GCC allows arrays to be returned from function - bug or feature? GCC allows arrays to be returned from function - bug or feature? arrays arrays

GCC allows arrays to be returned from function - bug or feature?


This was a bug in gcc (fixed as of 2017-07-03), caused by inconsistent treatment of trailing-return-types.

First note the difference in error message between two attempts to declare a function returning a function:

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

The first error comes from decl.c, handling declarators, while the second is a lot deeper into the internals, from tree.c, attempting to build the function type preparatory to generating code.

Trailing-return-types are handled in decl.c 30 lines below the above error - too late to catch it with the above error code, and it is not handled separately.

With arrays, similarly using a trailing-return-type allows us to skip the checks in decl.c, the difference being that function-returning-array is actually valid in terms of gcc's internal representation.

Note that you can't do much with it; gcc doesn't allow you to assign, reference-bind, decay or pass the result of func() to another function:

auto a1 = func();// error: invalid use of non-lvalue arrayauto& 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

Indeed, even your code is rejected at -Wpedantic:

warning: ISO C++ forbids subscripting non-lvalue array

Finally, by exploiting a similar bug (qualifiers are stripped from scalars before handling of trailing-return-types) we can create a function with type int const volatile():

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


Latest draft, [dcl.array]/p10:

Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things. There shall be no arrays of functions, although there can be arrays of pointers to functions.

This could be a non-standard GCC extension. It doesn't compile in the trunk version of clang. However, this may also be a bug since it has inconsistent behavior with a non-trailing return type.