9

From what I understood, I am passing the address of the variable a to the function int ffx1.

After that, what exactly does this line p = (int[2]){*p}; mean?

int ffx1(int * p)
{
    p = (int[2]){*p};
    return(p[1]);
}

int main()
{
    int a = 1;
    a = ffx1(&a);
    printf("%d", a);

   return 0;
}
msc
  • 33,420
  • 29
  • 119
  • 214
hago
  • 315
  • 2
  • 9

2 Answers2

12

With int ffx1(int * p), p is a pointer to an int.

(int[2]){*p} is a compound literal defining an int array of 2. @BLUEPIXY This unnamed array we will call X[2]. Its first element have the value of *p, and the next element, being an int will be initialized to zero (§6.7.9 21 & 10 ) as it is not explicitly listed.

p = .... assigned the pointer p to a new value. In this case, the above array X[]is converted to the address of its first enrollment or &X[0].

return p[1] de-references p, returning the value in X[1] or 0.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thanks. your answer is right.. But since it is mentioned p[1] and int[2] then what is the length of the unnamed array? 2 or 3? – hago Oct 31 '17 at 17:53
  • @hago The unnamed array, called `X[]` in this answer, consists of 2 elements because of the `(int[2])`. – chux - Reinstate Monica Oct 31 '17 at 17:54
  • Thanks. Good explanation. but here instead of writing p = (int[2]){*p}; can I write int *q = (int[2]){*p}; then what should be my return statement? return p[1] or q[1]? I guess q[1] right – hago Oct 31 '17 at 17:56
  • @hago Yes you can write `int *q = (int[2]){*p}` to avoid changing the local variable `p`. `return q[1]` would work like above. `return p[1]` would work with the original `p` passed in which does not pointer to 2 elements. – chux - Reinstate Monica Oct 31 '17 at 17:59
  • Why did you mention "all zero bit pattern" ? It happens to be true in this case, since `int` is defined as having all zero bit pattern for zero value; but if let's say it were an array of pointers, then the other entry gets the null pointer -- not necessarily all zero. The other entries are initialized as if by `{0}` – M.M Nov 01 '17 at 02:58
  • @M.M "Why did you mention "all zero bit pattern" --> Because I recalled it as that the memory will be filled with all zero bits as in `calloc()`. Yet non-explicit initialization in general is as you say - potentially not an all zero bit pattern - answer amended. – chux - Reinstate Monica Nov 01 '17 at 14:08
9

It is a pointer to compound literals.

C11-§6.5.2.5 Compound literals (p9):

EXAMPLE 2 In contrast, in

void f(void)
{
int *p;
/*...*/
p = (int [2]){*p};
/*...*/
}

p is assigned the address of the first element of an array of two ints, the first having the value previously pointed to by p and the second, zero. The expressions in this compound literal need not be constant. The unnamed object has automatic storage duration.

msc
  • 33,420
  • 29
  • 119
  • 214