5

I just got a question from my Friend.

#include<stdio.h>

void fun(int[][3]);

int main(void){
    int a[3][3]={1,2,3,4,5,6,7,8,9};

    fun(a);
    printf("\n%u",a);
    a++;//Ques 1

    printf("\n%u",a);
    printf("%d",a[2][1]-a[1][2]);

    return 0;
}

void fun(int a[][3]){
    ++a;//Ques 2
    a[1][1]++;
}

The line Ques 1 will throw an error of L value as 'a' is the name of a two dimensional array. But this is not happening with the case of line Ques 2.

Can any one clear this doubt?

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
Arivarasan
  • 285
  • 1
  • 7

3 Answers3

7

In Ques 1, a is an array and it will be converted to a non-lvalue pointer when used as operand of ++ operator and emit compile error.

In Ques 2, the argument int a[][3] is equivalent to int (*a)[3] and ++a is an increment of pointer variable, which is acceptable.

Quote from N1570 6.7.6.3 Function declarators (including prototypes), pargraph 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.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
2

When an array is passed as a function argument, it decays into a pointer to the array's first element.

Quest 1

a is an array, which is a non-modifiable lvalue. So it cannot be incremented.

Quest 2

The argument that is passed int a[][3]. This decays into a pointer to the first element, which is int (*)[3], (and not int *, contrary to common belief). A pointer may be incremented, so this works.

Also, you should be using %p for pointers in printf, and not %u.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
0

Okay, first, "L value" means something you can assign to. a is the name of an array. So what that line is trying to do is the same as if you were doing a = a + 1 on the array itself, which doesn't make sense.

Now, what you are running into here is that C has a somewhat confusing way of treating arrays: they're really just undistinguished chunks of memory, and their name is a limited alias to the address of the beginning of the array. When you pass an array, what C actually passes is the address of the array (or in this case, the address of a particular point in memory inside the array.) So at Ques 2, that's actually a pointer, which is an L value and can be incremented.

This is called "arrays decaying to pointers" (as pointed out in a comment) and yeah, it can be confusing.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263