0

...then why is the code below give same value (meatballs) for address and the actual content? And how to make sense of %d value of meatballs, is it random?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    int i;
    int meatballs[5]= {1,2,3,4,5};

    printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs, 
          meatballs);

    return 0;

}
1

2 Answers 2

3
  1. meatballs is an array, and it has type int[5]. However C doesn't allow passing arrays by value, so array decays into pointer for function call. This is equivalent of pointer to first element of array &meatballs[0], and it has type int*.

  2. &meatballs is a pointer to an array, and it has type int(*)[5]. Since it's a pointer it can be passed to a function.

As you can see, both 1. and 2. return same address, but they have different types: pointer to integer array vs pointer to single integer.

Note: Types void* and int* don't necessarily have the same representation(1), and for %p only valid type is void*(2) or you will get undefined behaviour(3). Always convert pointer to void* when printing addresses:

printf("%p %p", (void*)meatballs, (void*)&meatballs);
  1. Last situation is same as first, but you are using wrong type specifier %d. Resulting type is again int* as in case 1, but it is interpreted as int. This is clear undefined behaviour, and output is garbage.

To print integer array element, use any of the following methods:

printf("%d %d %d", meatballs[i], *(meatballs + i), *meatballs);

First two will print array element at index i, and last will print first element. I recommend using the meatballs[i] in most cases, as it's most clear.


References to C standard (draft):

  1. N1570, 6.2.5 paragraph 28

    A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.48)... ...Pointers to other types need not have the same representation or alignment requirements.

  2. N1570, 7.21.6 paragraph 8

    p The argument shall be a pointer to void. ...

  3. N1570, 7.21.6 paragraph 9

    ... If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

Sign up to request clarification or add additional context in comments.

6 Comments

Technically, there is no need to cast meatballs or &meatballs to void* as both are simply memory addresses which are void * to begin with. However, for the purpose of discussion it does no harm.
@DavidC.Rankin No, standard is pretty clear on this. void* is only required to have same representation as char* (N1570, 6.2.5 p28), and %p strictly requires void* (7.21.6 p8).
Unless you are interpreting it differently, that means there is no cast required between the char * and void * pointers for any purpose to the extent %p cares. Are you saying something else that I'm missing? They are compatible types. Specifically, note:48 addresses void * and char * compatibility: 48) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions
@DavidC.Rankin I was trying to say that void* and int* are not interchangeable, and that's why cast is needed on printf. But as you say, according to note 48, cast to char* should also suffice.
@alk Thank you. I added you suggestions.
|
0

You have to use the unary dereference operator *, so that the actual value is shown as %d expects an integer.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    int i;
    int meatballs[5]= {1,2,3,4,5};

    printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs, 
          *meatballs);

    return 0;

}

Look at the last parameter: *meatballs. This code actually prints 1 as value and is the first element in your array. So your guess is right and it is only a bug.

2 Comments

thanks for responding, now what about the meatballs and &meatballs having same value, are they allowed to be same if its a pointer.
@ManishKumarSingh name of array evaluates the addr of the first element in the array, so meatballs and &meatballs has same value. The next element array will not. e.g. meatballs+1 and &meatballs+1 .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.