0

I'm curious if I give an n-dimensional array for n>1 as an argument to a function, are the contents of whole array copied or just the pointer to the address of the first element.

Assume function signature is something like this:

int someFunction(int n, int arr[n][n]);
9
  • 3
    This is something that you could (a) easily try out and (b) do a little web searching for (e.g. c-faq.com/aryptr). Commented Mar 28, 2013 at 17:40
  • What do you mean by "array copied?" Nothing is copied on a function call. Just a pointer being passed in. Commented Mar 28, 2013 at 17:42
  • @LeorA - think again (what if an struct is passed) Commented Mar 28, 2013 at 17:43
  • 1
    @ChrisDodd: How would you distinguish "multidimensional array" from "array of arrays"? (Also note that the phrase "multidimensional array" is indeed used in the language standard...) Commented Mar 28, 2013 at 17:45
  • 1
    @ChrisDodd: I'm not sure that's intrinsic to the definition; that's just functionality. It doesn't have slicing for 1D arrays either... Commented Mar 28, 2013 at 17:50

2 Answers 2

4

[Where I just re-learned this yesterday]

This is a C99 extension that is not widely known. The array is still passed by reference as they always have been, but the compiler is able to interpret it as an array similar to the way it handles Variable-Length Arrays.

This won't give you bound-checking, of course. C doesn't have that.

In your function signature,

int someFunction(int n, int arr[n][n]);

The final n doesn't really buy you anything, it just gets ignored. But int arr[n][] is new. That's what C89 didn't have. Previously, the only option was to calculate indices manually off of the base pointer, arr[n*x+y].

In Ansi-C (C89), you'd have to declare the function as,

int someFunction(int n, int arr[]);

which is equivalent to

int someFunction(int n, int *arr);

and calculate the two dimensions as a single index.

The new C99 magic, reduces the original to this:

int someFunction(int n, int *arr[n]);

I'd describe the process more as array adoption, than passing. It just mitigates some of the losses that were incurred by the original decision to pass arrays as pointers.


It's important to understand that second two examples are sort-of internalized equivalents. Figurative illustrations. In the final one, the array is not converted into an array of pointers, but the bounds of the lowest dimension is dropped. Perhaps it's better illustrated like this:

int someFunction(int n, int arr[n][]);

The only way to copy an array as a function argument is to wrap it in a struct. But then you cannot have variable dimensions.

struct arr {int n; int arr[n][n];}; //Nope, won't compile!

enum { n = 3 };
struct arr { int arr[n][n]; };

struct arr someFunction( struct arr ); //argument and return value are copied.

And this has been legal since 1989.

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

3 Comments

Thanks, details in different versions of C are always confusing :)
int someFunction(int n, int arr[][]); is invalid C. And an array of pointers as you have in your last examples is different from a multidimensional array.
Thanks. I think I got confused by reading too much on tuhs.org. There are primitive versions which do accept that syntax.
-1

That's an illegal signature for a function, as arrays in function signatures must have constant dimensions (other than the final dimension).

The reason that arrays must have constant sizes as function parameters is because they aren't actually copied in the function call -- only a pointer is passed.

4 Comments

I would be inclined to agree… but GCC and Clang will both happily compile a function with that signature!
This is valid in C99, I believe... (see the examples in section 6.7.5.3)
Besides this answer being based on a false premise, I also don't see why you think that an array having a constant size has anything to do with whether it is copied or not.
It is correct per C89, and covers the rationale behind not allowing unspecified sizes on array dimensions other than the last one.

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.