Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can arrays be assigned directly?

Consider this code snippet:

void foo(int a[], int b[]){
    static_assert(sizeof(a) == sizeof(int*));
    static_assert(sizeof(b) == sizeof(int*));
    b = a;
    printf("%d", b[1]);
    assert(a == b); // This also works!
}

int a[3] = {[1] = 2}, b[1];
foo(a, b);

Output (no compilation error):

2

I can't get the point why b = a is valid. Even though arrays may decay to pointers, shouldn't they decay to const pointers (T * const)?

like image 605
iBug Avatar asked Nov 24 '17 07:11

iBug


2 Answers

They can't.

Arrays cannot be assigned to. There are no arrays in the foo function. The syntax int a[] in a function parameter list means to declare that a has type "pointer to int". The behaviour is exactly the same as if the code were void foo(int *a, int *b). (C11 6.7.6.3/7)

It is valid to assign one pointer to another. The result is that both pointers point to the same location.


Even though arrays may decay to pointers, shouldn't they decay to const pointers (T * const)?

The pointer that results from array "decay" is an rvalue. The const qualifier is only meaningful for lvalues (C11 6.7.3/4). (The term "decay" refers to conversion of the argument, not the adjustment of the parameter).

like image 191
M.M Avatar answered Oct 22 '22 23:10

M.M


Quoting C11, chapter §6.7.6.3, Function declarators (including prototypes)

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. [...]

So, a and b are actually pointers, not arrays.

There's no assignment to any array type happennning here, hence there's no problem with the code.

like image 41
Sourav Ghosh Avatar answered Oct 22 '22 22:10

Sourav Ghosh