简体   繁体   中英

Wrong format warning in this c program

I am trying to compile this program without warning,

#include<stdio.h>
int main()
{
    int arr[] = {1,2,3};
    printf("value1 = %d value2 %d\n", *(&arr+1), *(arr+1));//here is the warning
    return 0;
}

But I am getting a compile time warning

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]

I am compiling my program on a 64 bit ubuntu machine gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) compiler.

&arr takes the address of the array, it is an array pointer (not to be confused with pointer to 1st element). It has type int(*)[3] .

Then you do pointer arithmetic on this array pointer. Since it points at an array of 3 integers, &arr + 1 will mean "plus the size of one whole array" and you end up pointing just past the declared array, which doesn't make any sense.

Then you take the contents of the array pointer with * . You will then get the array itself again. When you an array in an expression, it decays into a pointer to its first element, int* . Which is not compatible with int , hence the error.

I'm guessing you were probably trying to do either &arr[0] + 1 or arr + 1 , which both mean the same thing.

arr has the type of int (*)[3] , other than int * , although in most cases, array names decay into pointers to first elements, that is &arr[0] in your second case, and this is exactly why your value2 is output normally.

However, when arr is the argument of the & operator, it doesn't decay. As a result, &arr+1 has the equivalent value as &arr[0]+3 . This is because sizeof &arr is equal to sizeof (int (*)[3]) , which yields 3. Consequently, when trying to output value1 , your are actually accessing &arr[3] , whose type is int * . It's &arr[3] , not arr[3] , because when you dereference something has the type of int (*)[3] , it decays to a pointer.

So as you can see, the warning is indeed trying to save you from a potential error.

See also: Exception to array not decaying into a pointer?

Step-by-step:

arr is type "array 3 of int".

int arr[] = {1,2,3};

&arr is type "pointer to array 3 of int".

&arr + 1 is also type "pointer to array 3 of int".

*(&arr+1) is type "array 3 of int".

When an array is passed to a function, a conversion occurs. The address of the first element of the array is passed, not the array itself. In this case it has the type of int * .

The "%d" expects a matching int , so the compiler warns:

format '%d' expects argument of type 'int', but argument 2 has type 'int *'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM