2

can anyone please let me know what's the difference b/w

int vector[]={10,20,30}
int *p = vector

and

int *p= &vector

I know by mentioning array name, we get it's base address . The second statement is giving me warning

initialisation from incompatible pointer type

Why warning, both statement give array base address.

user8422062
  • 59
  • 1
  • 3

3 Answers3

4

When used in an expression, an array name will in most cases decay to a pointer to its first element.

So this:

int *p = vector;

Is equivalent to:

int *p = &vector[0];

The type of &vector[0] is int *, so the type is compatible.

One of the few times an array does not decay is when it is the object of the address-of operator &. Then &array is the address of the array and has type int (*)[3], i.e. a pointer to an array of size 3. This is not compatible with int *, hence the error.

Although the address of the array and the address of its first element have the same value, their types are different.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

&vector is of type int (*)[3] i.e. a pointer to an array, whereas vector without & would decay to int * pointing to the first element.

int (*)[3], even though pointing at the same address is incompatible with int *, hence your program has a constraint violation, which makes your program an invalid program, and a compiler must issue a diagnostics message.

The C standard explicitly mentions in a [footnote (C11 footnote 9) that a compiler is allowed to successfully compile an invalid program:

9) The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.

I.e. a compiler is allowed to do whatever it pleases with the given source, provided that a valid program is correctly translated. Hence many compilers will look these kinds of things through the fingers with default settings and provide a translation that has more or less expected - or equally unexpected - results, and you will get only a warning.

2

Expressions in C have both values and types.

Given int vector[] = {10, 20, 30};, vector is an array. C has a rule that, when an array is used in an expression outside of certain places1, it is automatically converted to be a pointer to its first element. Then its value is effectively the address of the start of the array2, and its type is “pointer to int”.

The expression &vector takes the address of the array. This is different from the address of its first element. Largely, they both have the same value. Both the array and its first element start at the same place in memory. But they have different types. The type of &vector is “pointer to array of 3 int”.

C has rules about types, and you cannot automatically use one type where another is expected. Sometimes types are converted automatically, as when a narrower integer is converted to a wider integer. But, generally in places where the type is important to the meaning of the software, there are no automatic conversions (or limited conversions). If you try to assign a pointer to an array to a pointer to an int, a good compiler will warn you you are doing something improper.

When a pointer to one type is assigned to a pointer to a different type, it might be because the programmer has made a mistake. This is why the compiler warns you.

Additionally, the same value with different types may behave differently. Because array is a pointer to its first element, a + 1 is a pointer to the second element. But, since &array is a pointer to the array, &array + 1 is a pointer to the end of the array (where the next array after it would start, if there were one).

Footnote

1 An array is not automatically converted when it is the operand of sizeof or the operand of unary & or is a string literal used to initialize an array.

2 The array starts in the same place in memory that its first element starts, of course. So they have the same virtual address. So they have the same value in that sense. However, there are some technical issues about C pointers that mean two pointers to the same place may not be exactly the “same” in certain senses. In this answer, I will not get into details of that. We can treat pointers to the same place as the same in this discussion.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312