1

I understand C++ passes arrays by reference even if we don't use the reference operator (&), but since it can be added with no harm (I think), I'm curious as to why this code throws

declaration of 'matrix' as array of references

void function (int &matrix[2][5])  {
    //something
}

int main()  {
    int matrix[2][3] = {{1,2,3}, {4,5,6}};
    function(matrix);
}

while adding parentheses in (&matrix) works:

void function (int (&matrix)[2][5])  {
    //something
}
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Floella
  • 1,279
  • 1
  • 22
  • 41
  • 1
    Use `std::array` or `std::vector` instead. – Ron Oct 05 '18 at 11:20
  • 3
    Because two different syntax mean two completely different things? Reference to array of ints != array of int references. – Yksisarvinen Oct 05 '18 at 11:20
  • 2
    *"I understand C++ passes arrays by reference"* it doesn't – UnholySheep Oct 05 '18 at 11:21
  • C++ does not pass arrays as references. – melpomene Oct 05 '18 at 11:21
  • Arrays are not passed to functions at all; a pointer to the first element is passed instead. – molbdnilo Oct 05 '18 at 11:23
  • Doesn't C++ pass a reference to the first element of the array? How is that different from "passing an array by reference"? Or it's just a matter of wording? – Floella Oct 05 '18 at 11:24
  • 3
    No. Pointers are ultimately different concept than references. You may want to check [a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Yksisarvinen Oct 05 '18 at 11:26
  • 1
    @Floella While you *could* say, in everyday English, that a pointer ”refers to” an object, that’s not what ”reference” means in C++. A pointer is not a reference, and vice versa. – molbdnilo Oct 05 '18 at 11:30

2 Answers2

4

&matrix[2][5] has a different meaning from (&matrix)[2][5]).

The former means matrix is a two dimensional array of references to int and the latter means matrix is a reference to a two dimensional array of integers.

Since matrix is defined as a two dimensional array in main, the second form succeeds.

The cdecl tool can be helpful here:

int (&matrix)[2][5] - declare matrix as reference to array 2 of array 5 of int
int &matrix[2][5] - declare matrix as array 2 of array 5 of reference to int
P.W
  • 26,289
  • 6
  • 39
  • 76
2

I understand C++ passes arrays by reference even if we don't use the reference operator (&)

This is incorrect. C++ doesn't pass arrays as references. Additionally, there is no such thing as a "reference operator".


I'm curious as to why this code throws

The code is not "throwing", that term is used in the context of exceptions. You are simply getting a compilation error, as you're attempting to define an array of references to integers.

This happens because

int &matrix[2][5]

is grouped as

int &((matrix[2])[5])

by default. Adding parenthesis makes the compiler parse your type as "reference to an array of integers".

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 1
    No, it's grouped as `&((matrix[2])[5])` because `[]` has higher precedence than `&`. – melpomene Oct 05 '18 at 11:28
  • Thanks. English not being my native tongue, I chose the word "throws" in the wrong context, although I see there are no exeptions anywhere on my code. About the & operator, I've always called it "reference operator" as it gets you a reference. So how exactly is this operator called? Thanks. – Floella Oct 05 '18 at 11:50
  • 1
    It's not an operator, operators are just "functions" with special syntax. This is part of the declaration syntax for references, I'm not sure if it has a particular name apart from... reference? – Vittorio Romeo Oct 05 '18 at 11:58
  • 1
    @Floella `&` in declarations is very different from `&` in expressions. In declarations it means "reference", but as an operator in expressions it means "address of" (or "pointer to"). Blame the C++ designers for the inconsistency. – melpomene Oct 05 '18 at 12:07