4

I have this code:

#include <stdio.h>

int main()
{
    int arr[10] = {0};
    int *p1_arr = arr;
    int (*p2_arr)[10] = arr;      // Line 7, Shows Warning here

    ...

    return 0;
}

On compiling on gcc using gcc -g -Wall LengthofArray.c, it shows following warning:

gcc: LengthOfArray.c:7: [Warning] assignment from incompatible 
                         pointer type [enabled by default]

My question is if int (*p2_arr)[10] is a pointer to an array of size 10, then why compiler shows this warning?

Also what is the correct way then?

I used gcc 4.7.2 on Windows 7 32-bit (DevC++)
and also checked on gcc 4.1.2 on SLES 10.3 x86_64

0xF1
  • 6,046
  • 2
  • 27
  • 50
  • The point to understand is both `&arr` and `arr` both semantically different. (of-course value is same if you print using `%p`). – Grijesh Chauhan Oct 19 '13 at 11:42
  • Read [What does `sizeof(&array)` return?](http://stackoverflow.com/questions/15177420/what-does-sizeofarray-return/15177499#15177499) – Grijesh Chauhan Oct 19 '13 at 11:42

3 Answers3

5

... if int (*p2_arr)[10] is a pointer to an array of size 10 ...

As p2_arr points to an array of size 10, you need to assign an address of an array of size 10:

int (*p2_arr)[10] = &arr;   
alk
  • 69,737
  • 10
  • 105
  • 255
  • Right, I got confused. The name of array is an `int` pointer not a pointer to `array of 10 ints`. Thanks anyways. – 0xF1 Oct 18 '13 at 16:26
  • 3
    @0xF1: The name of the array names the array, not an `int` pointer. An array is **converted** to a pointer to its first element in most expressions, but not all of them. So you can see that the name of the array does indeed name the array in `sizeof`, `&`, and `_Alignof` expressions. – Eric Postpischil Oct 18 '13 at 16:32
  • @tfinniga This is C, not C++. No warning will/shall be emitted if you assign **any** (non-qualified) object pointer type to a `void *`. –  Oct 18 '13 at 20:32
4

arr (as any array) decays into a pointer to its first element (and not to a pointer to the array itself), which is an int *. To get the correct behavior, take its address, like this:

p2_arr = &arr;
  • @tfinniga Um what? That's wrong. `arr` is not the same as `&arr[0]`, it only is implicitly converted so. (Don't downvote if you don't know what's going on...) –  Oct 18 '13 at 20:29
  • @tfinniga And even if it was: your "reasoning" is simply nonsense. What's with all those "strict types"? Just wrong. It's just that OP tries to assign to a pointer to an incompatible type. –  Oct 18 '13 at 20:35
  • @tfinniga (as to why the explanation is nonsense: it's a classic non sequitur. There's no such thing as a "more strict type", there are only compatible and incompatible types. I suggest you read the relevant parts of the standard before criticizing others' answers in an unjust way.) –  Oct 18 '13 at 20:59
  • after reading the question and your answer more carefully, I must apologize. I misunderstood your answer, which I now see is correct. – tfinniga Oct 21 '13 at 10:43
  • @tfinniga I've edited my answer so it's not locked - if you downvoted, could you revoke it? –  Oct 21 '13 at 11:56
  • Sure thing. I tried to switch to an upvote earlier, but as you guessed it was locked; I just switched my vote. Again, sorry for my misunderstanding. – tfinniga Oct 21 '13 at 12:20
2

Why compiler says assignment from incompatible pointer type ?

  • arr is converted to type pointer to int

    Name of the array decays into a pointer of type, pointer-to-T to the array's first element. (Exceptions to this are : when the array is the operand of a sizeof or & operator, or is a string literal initializer for a character array. Read this) T is type of array element.

  • p2_arr is of type pointer to array of 10 int

    This is self explanatory and clear from your declaration of p2_arr

Hence, you can't assign arr to p2_arr


Solution:

Now, to assign a valid pointer expression to p2_arr, you will need address of array of 10 int.

  • &arr is of type pointer to array of 10 int

You can do,

int (*p2_arr)[10] = &arr;
Community
  • 1
  • 1
smRaj
  • 1,246
  • 1
  • 9
  • 13