7

Any historical or logical reasons behind it?


Explanation: when you pass an array to a function in C you actually only pass a pointer to an array. However, when you pass a struct, you can either pass a copy of the struct or the pointer.

//this:
int function(int array[10])
// is equivalent to this:
int function(int *array)
//and they both pass a pointer

//but this:
int function(struct tag name)
//passes a struct by value, where as this:
int function(struct tag *name)
//passes a pointer to it.

Why the difference?

12
  • 1
    You can pass an array by value, but the value of an array is a pointer to its first element (not a pointer to the array). Commented Jul 23, 2016 at 16:18
  • a pointer to a struct is also a pointer to it's first value, if i'm not mistaken Commented Jul 23, 2016 at 16:19
  • 1
    No, those are different (the types don't match, for one). Commented Jul 23, 2016 at 16:21
  • 1
    Possible duplicate of stackoverflow.com/questions/36872230/… Commented Jul 23, 2016 at 16:21
  • 3
    I think this question belongs more on programmers.SE. It might be worth noting that K&R C didn't allow value-passing/returning structs. Commented Jul 23, 2016 at 16:24

5 Answers 5

11

In the original K&R, you could not pass structs by value. That was a syntax error. Because many compiler vendors offered it as an extension, pass-by-value eventually made its way into the standard.

Why the restriction, and why the evolution? The machines that C was developed on were tiny. Segment sizes of 64 kilobytes were common. Memory was precious, so why copy something when you could just pass the address? Duplicating a 64-byte structure on the stack was an error, probably not even what the user intended.

By the mid-1990s, that wasn't true anymore. 32-bit addressing and RAM of 4 MB or more were common. The restriction was a hinderance and led to some complexity, because without const a structure passed by reference could be modified, perhaps unwittingly.

Why not do the same with arrays? No demand. Arrays and pointers are closely related in C, as you know. The C standard library depends heavily on passing by reference, consider memset and strcpy. Whereas passing a struct by value meant just dropping the & on the call, passing an array by value would have entailed adding new syntax. A compiler vendor that offered, say, by value as C syntax would have been laughed out of the conference.

Sign up to request clarification or add additional context in comments.

Comments

0

int function(int array[10]) and int function(int *array) are the same because of 6.7.5.3 Function declarators (including prototypes) (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf page 118)

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

.

Comments

0

Of course, you can pass an array by value; all you need to do is wrap it in a struct. But that only works if the array has a definite (and non-variable) size. You can include an indefinitely sized array in a struct, but the resulting type is incomplete and can only be used as the target of a pointer.

That's probably as close as we're going to get to an explanation. The vast majority of arrays passed as arguments are not of fixed size, and passing them by value would not be possible, even if it were intended, which is also unlikely.

There is a similar (but different) decay with functions; a function cannot be passed as an argument, only function pointers. Since it would be tedious to explicitly write & every time you wanted to refer to a function, the language takes care of it for you.

On the whole, questions of the form "Why is this language like this snd not like that?" can only be answered "because that's how it is".

Comments

-1

Types are different in both function declarations -

struct tag  /* and */ struct tag *

One is structure variable whereas another is pointer to structure.

You can do similar with structures -

int function(struct tag name[])  /*--> int function(struct tag *name)  */

These above would be equivalent.

7 Comments

huh? how does this answer the question?
@DavidRefaeli I would assume . I think OP wasn't aware about this else he would not be confused about it . Question seems to me in that way because all decalrations in question desn't compare.
@ameyCU "I would assume" does not answer "how?". And DavidRefaeli is the OP.
@ameyCU - I don't think you understand the question. I'm asking why is it that in C you can pass a copy of struct to a function, but you can't pass a copy of an array...
@ameyCU Yes, and it seems the question is "why?".
|
-1

structs are used for declaring own kind of data types with primitive data types like int,float,long(or structs of structs) etc. they are supposed to hold a few of them e.g. struct of students will contain id,name,rollno,subjects,etc. so mostly any struct element will contain 10-20 fields at most (in logical cases), so when you pass a struct to a function, it has to copy 40-100 bytes approx. to make copy of that struct variables. where as arrays can be of huge size and are used to store same kind of information. they can be of size 10^7 in case of integers so if we implement a language to copy whole array for function calls it may have to copy (10^7)*4 bytes which is a huge amount and will impact the performance badly.and typical size of arrays is 10^4 to 10^6 which is still a lot. but if you create struct of array of int(or any other array) you can pass it to a function as a copy of that array. e.g.

#include<stdio.h>

typedef struct {
    int arr[10];
}arrayStruct;

void change(arrayStruct a){
    a.arr[2]=5;
}
int main(){
    arrayStruct a;
    for(int i=0;i<10;i++){
        a.arr[i]=i;
    }
    printf("Before:\n");
    for(int i=0;i<10;i++){
        printf("%d ",a.arr[i]);
    }
    change(a);
    printf("\nAfter:\n");
    for(int i=0;i<10;i++){
        printf("%d ",a.arr[i]);
    }
    return 0;
}

this is not done in most of the cases but few times when you need to pass arrays but don't want to alter the contents of them but also require some kind of changes to their copies and want to return that copy you can use this kind of structs of arrays and return them from functions of return type of structs e.g.

arrayStruct returnChange(arrayStruct a){
    a.arr[2]=332;
    return a;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.