In C:
When a struct is sent (via a parameter) by value in to a function, a new struct is created, so changing the structure inside the function won't change the original structure.
When an array is sent (via a parameter) by value in to a function, a new pointer is created, so changing the array inside the function won't change the original array, but changing array values inside the function (since we have the pointer to the original array) will change the values in the original array.
When a struct with an array field is sent (via a parameter) by value in to a function, ????? is created, so that changing the array (pointer) inside the function won't change the original array and changing array values won't change the values in the original array.
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned? Why isn't just the pointer used instead? What does the specification say about it?
A piece of code that I've played with:
typedef struct {
int value;
int array[3]; /* initialized to 0 by default */
} Struct_t;
void foo(Struct_t structure)
{
printf("-- %p\n", structure.array); /* Pointer to local array */
structure.value = 1;
*structure.array = 1; /* Won't change the original array */
*(structure.array + 1) = 1; /* Won't change the original array */
structure.array[2] = 1; /* Won't change the original array */
}
int main()
{
Struct_t s = { .value = 0 };
foo(s);
printf("-- %p\n", s.array); /* Pointer to original array */
printf("%d\n", s.value);
printf("%d\n", s.array[0]);
printf("%d\n", s.array[1]);
printf("%d\n", s.array[2]);
}
Output:
-- 0x7ffe8f17d194
-- 0x7ffe8f17d1b4
0
0
0
0
OP's "When an array is sent ..." needs clarification.
When an array is sent (via a parameter) by value in to a function, a new pointer is created, so changing the array inside the function won't change the original array, but changing array values inside the function (since we have the pointer to the original array) will change the values in the original array. (OP)
When an array, like s[]
below, is passed to strcpy(char *s1, const char *s2)
, a conversion occurs first. The object s
is converted to the address of the first element of the array. strcpy()
does not receive s[]
as the s1
parameter, instead it receives a copy of the value of of &s[0]
.
char s[6] = "Hello";
strcpy(s, "World");
Within strcpy()
, s1
is not an array. s1
is a pointer to a char
. strcpy()
has no concept of "changing the array inside the function" as the function does not know s1
points to array memory, allocated memory or anything else. strcpy()
understands s1
points to a char
.
Does the third point mean that an array field of a struct, when sent in to a function will be entirely cloned?
Yes. When an object is passed to a function in C, it is potentially converted and then passed by value. It is much like any assignment. The contents of the object, after conversion is copied to the destination. It makes no difference, after conversion, if the object is a struct, union, int, double, void*, int(*)()
etc or a struct
containing an array.
int a;
double b;
a = 5; // 5 is copied to a
b = a; // a is converted to double and copied to b
char s[6] = "Hello";
char *e;
void *v;
e = s; // s is converted to the address on the first array element and then copied to e
v = e; // e is converted to a `void*` and then copied to v
Struct_t f = {0};
Struct_t g;
g = f; // f is copied to g