开发者

Pass by value possible in C?

开发者 https://www.devze.com 2023-03-30 15:12 出处:网络
Hello I was reading this question, I got confused with how if we can pass arrays by value or not. Here is a piece of code which I think should pass array by value.

Hello I was reading this question, I got confused with how if we can pass arrays by value or not. Here is a piece of code which I think should pass array by value.

#include <cstdio>
void foo (int arr[]);
int开发者_Go百科 main()
{
    int arr[10];
    foo(arr[10]);
    return 0;
}
void foo (int arr[])
{
.......
}

Please tell me why wouldn't it pass by value?

Thanks


Arrays automatically decay into pointers in certain contexts in C. Function calls are one of those places. That said, you are passing the pointer by value - C has no other way to pass parameters than "by value".


Because this:

void foo(int arr[])

is really just syntax sugar for this:

void foo(int *arr)

So when you call the function, your array decays into a pointer to the first element.


In short: you cannot pass an array as a function parameter and have it received as an array type by the called function. An array expression in that context will be converted to a pointer type before it is passed to the function.

From the C language standard:

6.3.2.1 Lvalues, arrays, and function designators
...
3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

What this means is that when you write something like

int arr[10];
foo(arr);

the expression arr in the call to foo is immediately converted to a pointer type; it is said to "decay" to type int *. So all foo will ever receive is a pointer value.

More standard language:

6.7.5.3 Function declarators (including prototypes)
...
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

What this means is that if your prototype for the function foo is either

void foo(int arr[])

or

void foo(int arr[10])

it will be interpreted as

void foo(int *arr)

Again, the definition of the language is such that you cannot pass an array expression as a function parameter and have it be received as an array type by the called function.

There are ways around this; you can wrap the array in a struct and pass the struct by value, like so:

struct T { int arr[10]; } var;
foo(var);
...
void foo (struct T arg) { ... }

As hacks go, this doesn't really buy you much.

0

精彩评论

暂无评论...
验证码 换一张
取 消