1

Is it possible to pass raw table to function by value? I believe that it's impossible, but I'm looking for official sources to confirm that.


I know how to pass table by reference:

template<typename T, size_t N, size_t M>
void first_example(T (&table_in_function)[N][M]) {
  //...
 }
 //...
int a[50][20];
//...
first_example(a);

or by std::array, but as I sad, I'm looking for solution for raw tables. Simple idea, remove &, is obviously wrong. Also I am not looking for something like:

template<typename T, size_t N, size_t M>
void third_example(T (&temp_ref)[N][M]) {
  T local_table[N][M];
  //...
 }

I accept solutions like magic code and meta-programming.

Tacet
  • 1,411
  • 2
  • 17
  • 32

3 Answers3

2

The canonical way to handle this is to use std::array (or an equivalent wrapper type).

Beyond that, you are out of luck, because C++ bans direct copy-initialisation of arrays:

[C++11: 8.5/16]: [..] The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.

  • If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).
  • If the destination type is a reference type, see 8.5.3.
  • If the destination type is an array of characters, an array of char16_t, an array of char32_t, or an array of wchar_t, and the initializer is a string literal, see 8.5.2.
  • If the initializer is (), the object is value-initialized.
  • Otherwise, if the destination type is an array, the program is ill-formed. [..]

The only reason that you can appear to pass arrays directly into functions is, as you know, because their names actually decay to pointers (resulting in what I call pass-by-handle). Despite appearances in consequential usage syntax, this is functionally not any different for you than pass-by-reference.

The above quote means that anything you could do to work around array name decay would only see you run into the more fundamental problem that arrays may not be directly copied.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Therefore I noticed, It's syntactic sugar question. I know, how to deal with this problem normally. – Tacet Apr 28 '15 at 23:48
  • @Tacet `std::array` is not quite syntactic sugar, it is probably implemented as a templated array stored inside a `struct`. Then the default copy constructor of the `struct` will copy the elements when you pass by value. – vsoftco Apr 28 '15 at 23:51
  • @Tacet: I'm not sure that "syntactic sugar" means what you think it means. Regardless, I stand by this answer. If you don't want to pass-by-reference, or pass-as-pointer, or wrap in something like `std::array`.... then you can't do anything. And that's that. – Lightness Races in Orbit Apr 28 '15 at 23:54
  • It means and yes, I don't. However, I want be sure of that. Thank you for your answer. – Tacet Apr 29 '15 at 00:00
  • lol a downvote... how quaint. – Lightness Races in Orbit Apr 29 '15 at 00:00
2

It is impossible to declare a function parameter of array type. In particular the C++ standard (§8.3.5/5) specifies:

After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively.

So, if you attempt to create a function taking a parameter with array type, that parameter will be "adjusted" by the compiler to become a pointer instead.

Likewise, when/if you attempt to pass an array to a function, the what will actually be passed is the address of the first element of that array.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

This is impossible. C-style arrays automatically decay to pointers when passed into a function.

You'll have to explicitly copy the array.

orlp
  • 112,504
  • 36
  • 218
  • 315