Reputation: 732
The output of the following code segment is 9. I think the argument, a
, of the function foo
is passed by value. Is my assumption correct? If so, how does the output become 9?
#include <stdio.h>
void foo(int[][3]);
int main(void)
{
int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
foo(a);
printf("%d\n", a[2][1]);
return 0;
}
void foo(int b[][3])
{
++b;
b[1][1] = 9;
}
Upvotes: 2
Views: 146
Reputation: 4245
The compiler won't copy the entire array. If its passed by value, pass an array of 100000 elements. So its passed as a "Pointer". The address is passed as a copy, I guess. So changing the contents of the address I would change the original thing too.
It seems like pass by reference by a pointer.
Upvotes: 0
Reputation: 3663
The output of your program is 8 as expected. There isn't anything unexpected here. In b[2][1] = 9
, after incrementing b
, you are writing 9 to the location a[3][1]
. It doesn't affect the output of a[2][1]
which remains 8 before and after you call foo()
.
You certainly need to recheck your output.
Upvotes: -1
Reputation: 3156
According to: 6.2.3.1/3 & 6.7.5.3/7
In the call to foo, the array expression arr isn't an operand of either sizeof or &, its type is implicitly converted from "array of int" to "pointer to int" according to . Thus, foo will receive a pointer value, rather than an array value.
So when you do:
void foo(int b[][3])
it is being implicitly converted to:
void foo((*b)[3])
Upvotes: 0
Reputation: 225192
The []
syntax for a function parameter's type is just syntactic sugar. A pointer is passed in this case, just like with any other use of an array in a function call context. That means your foo()
function's signature is equivalent to:
void foo(int (*b)[3])
That is, it accepts a pointer to an array of three integers. With that in mind, let's look at what your implementation does. First, ++b
advances the pointer to point to the next array of 3 integers in memory. That is, it advances b
by 3 * sizeof(int)
. In the case of your program, that means it's pointing at the "middle row" of a
- the { 4, 5, 6 }
row.
Next, you access element [2][1]
of the new b
. That is, row two, element one of this new offset logical array. That causes your program to write to an address past the end of a
, which is undefined behaviour. At this stage, all bets are off. The output of your program could be anything.
You can get back to defined behaviour by changing that line to:
b[1][2] = 157;
for example. Then, print a[2][2]
to see the change from the context of your main()
function.
Upvotes: 2