Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong format warning in this c program

Tags:

c

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.

like image 416
mrigendra Avatar asked Feb 08 '23 22:02

mrigendra


2 Answers

&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.

like image 178
Lundin Avatar answered Feb 10 '23 13:02

Lundin


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?

like image 44
nalzok Avatar answered Feb 10 '23 13:02

nalzok