2

I have a multidimensional array of fixed size in my code, and I need to be able to change the values within it in a separate function. I want to know, are std::arrays passed as references in a method or is a copy made? So can I do this:

using std::array;

void foo (array<array<int,WIDTH>,HEIGHT> bar);
//manipulates the values in the array
...

int main() {
  array<array<int,WIDTH>,HEIGHT> baz;
  ...
  foo(baz);
  //baz is changed
}

Or do I need to explicitly turn it into a reference? I fear that if I created an array function that returned a copy, it would be too messy and not as fast.

8
  • 2
    std::arrayis a regular class that behaves in regular ways. There are no types that get special treatment as parameters. Commented Aug 31, 2018 at 4:50
  • I assumed since it was a wrapper for c arrays that it would also be passed as a reference. Commented Aug 31, 2018 at 4:52
  • If you have an ordinary class definition that contained a C array, and then passed an instance of that class by value, the internal array member field would get copied into a new instance. std::array does not behave differently. Commented Aug 31, 2018 at 4:54
  • I guess you're thinking of a C array's decaying into a pointer to its first element as a parameter. Note that in that case, the parameter does not have the same type as the array. The actual argument, which is a pointer, is copied like everything else. Commented Aug 31, 2018 at 4:56
  • 2
    @Comrade_Comski I imagine one of the design aims of std::array was to get away from the special treatment that regular arrays get. Otherwise what's the point? Commented Aug 31, 2018 at 5:57

2 Answers 2

4

I want to know, are std::arrays passed as references in a method or is a copy made?

std::array is a value type. If you pass by value, a copy will (conceptually) be made.

This is different from the behaviour of a c-style array (int bar[HEIGHT][WIDTH]). c-style arrays are passed by reference. This is due to a fundamental design decision (some would say error) in the C language many moons ago.

do I need to explicitly turn it into a reference?

If you wish to pass a reference, yes.

I fear that if I created an array function that returned a copy, it would be too messy

Functional programmers would argue that it was cleaner.

and not as fast.

Be careful of assumptions like this. For amongst other reasons,

a) Compilers don't always do as you tell them. They can write code that has the same effect as if they'd done what you tell them, but achieves the same result quicker. (google: "as-if rule c++")

b) Modern CPU architectures are specifically engineered to be extremely good at moving contiguous blocks of memory.

Write the cleanest code you can which, using abstract concepts to express your intent clearly. If the program runs too slowly, uses too much memory, uses too much power or your end users are complaining, then maybe is the time to concern yourself with by-reference or by-value optimisations.

However, I can assure you that any delays you are seeing in execution speed are much more likely to be in your treatment of IO or due to the selection of algorithms exhibiting high time complexity.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you. Should I choose to return a copy, is the function guaranteed to delete the extra copy after it is finished?
@Daniel yes. Often the extra copy won't even be made. Compilers are pretty clever.
Pretty common as well: pass parameters by const reference, return a newly created result (Matrix add(Matrix const& x, Matrix const& y);)
@RichardHodges I am a bit in trouble with "C-style arrays being passed by reference" - as for my underständing, if it was so, 1. there shoudn't be a change of type (array decaying to pointer), 2. sizeof should yield size of array, not size of pointer. Even worse: one can really pass arrays by reference: void f(int (&x)[7]) (apart from that detail, fine answer...)
@Aconcagua 1. yes, this is exactly what happens in reality. 2. welcome to the mess that is c-style arrays passed to functions. and yes, your example of f means exactly the same as if you had written void f(int x[7])
|
3

Pass by reference (or pointer) if you want to avoid having a copy made:

void foo (array<array<int,WIDTH>,HEIGHT> &bar);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.