-1

It's common wisdom that you can't return a reference to an array. I've read Why doesn't C++ support functions returning arrays? and one of the answers goes into long winded speculation that it's a design decision. Another answer suggests using a vector or struct instead (what??) and also says:

The array you return would degrade to a pointer though, so you would not be able to work out its size just from its return.

But it's also common wisdom that you can preserve the size of an array by using a reference. The following works for example:

int arr[10];

int (&func())[10]
{
    return arr;
}

int main()
{
    int (&arr)[10] = func();
    for (int i = 0; i < 10; ++i)
        std::cout << i << " ";
}

Aside from the usual "you should use a vector or std::array" what's wrong with this approach? I'm unable to see why people care so much about returning an array when this is possible.

  • 3
    Well this isn't going to work well if the array is local to the function (which is the case most people are talking about). – Joseph Mansfield Mar 06 '15 at 23:30
  • 3
    It makes as much sense as returning a reference to anything else: the reference has to refer to an object that is valid on the caller side. – juanchopanza Mar 06 '15 at 23:33
  • You can return a reference to array just fine (or a pointer to array, too). The problem is the lifetime. – T.C. Mar 06 '15 at 23:40
  • Well done, you've shown how to return something that is already available to the caller anyway. And every time you call the function you get the same array. Yay. This seems really useful. – Jonathan Wakely Mar 06 '15 at 23:48
  • 1
    Also did you mistype the first sentence of the question? – Jonathan Wakely Mar 06 '15 at 23:49
  • @JonathanWakely Well, it's slightly more useful if `arr` is in a different translation unit and has internal linkage... – T.C. Mar 06 '15 at 23:50
  • You still get the same one every time. It's just a global, even if the array isn't directly visible and you access it via a function. That's one kind of function, but it's of pretty limited use. – Jonathan Wakely Mar 06 '15 at 23:53

3 Answers3

1

You seem dismissive of vector. However make sure you clearly understand that vector really is the C++ equivalent of an array in Java and many other popular languages. Don't be misled by the slightly different declaration syntax. The beast in C++ that uses [] is very different to a Java array.

Moving onto your question: Yes, you can return a C-style array by reference. Your code is correct. But there are very few use cases for it, which is probably why you haven't seen it before.

In modern C++, it is preferred to avoid using C-style arrays because they do not follow value semantics that other objects have. (For example, they cannot be returned by value from a function). They're an ugliness inherited from C that unfortunately it's too late to delete from the standard entirely.

std::array<int, 10> may look ugly to you at first, however it will behave nicely when you try to copy or move or return it.

M.M
  • 138,810
  • 21
  • 208
  • 365
1

The code you wrote is perfectly acceptable. There are a number of reasons why it isn't done more often:

  • The size of the array must be fixed at compile time. Many functions returning an array would like to return a variable number of elements.
  • The storage can't be local to the function, or if it is it must be static. You never want to return a reference to an object that no longer exists. It may appear to work, which is actually a bad thing - you won't notice your mistake right away. Your test case is quite artificial, you don't often return a reference to a global.
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

Another answer suggests using a vector or struct instead (what??)

A struct is copyable, so if you embed an array inside a struct you can return it like a normal value type. You can't do that with an array.

I'm unable to see why people care so much about returning an array when this is possible.

Because what you've done is just not very useful, it's just an accessor to a global array. You're not returning a new array, just the same one each time. This fails:

auto arr1 = func();
auto arr2 = func();
arr1[0] = 1;
arr2[0] = 2;
assert( arr1[0] == 1 );   // fails

The people who want to return an array from a function want to return a different array each time the function is called, not just a reference to the same one every time. The same way you can call a function returning int and it's a different value each time and separate calls don't return references to the same piece of state. You haven't solved their problem, you've just done something else.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521