8

In unqlite c library I found following code:

 pObj = jx9VmReserveMemObj(&(*pVm),&nIdx);

where pVm is:

typedef struct jx9_vm jx9_vm;
jx9_vm *pVm

and function called is declared as:

jx9_value * jx9VmReserveMemObj(jx9_vm *, sxu32 *);

What for construct &(*pVm) is used in call instead of just pVm? Is &(*pVm) equivalent to pVm?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
shibormot
  • 1,638
  • 2
  • 12
  • 23

3 Answers3

13

Quoting C11, chapter §6.5.3.2, Address and indirection operators

[...] If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. [...]

So, yes, they are equivalent.

This construct can be used, however, to check the type of the argument against a pointer type. From the property of unary * operator,

The operand of the unary * operator shall have pointer type.

So, the construct &(*pVm)

  • will be fine, if pvm is a pointer or array name.
  • will generate compiler error, if pvm is a non-pointer type variable.

See the other answer by Alter Mann for code-wise example.

One more difference (in general) is, pVm can be assigned (can be used as LHS of the assignment operator), but &(*pVm) cannot.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 2
    "*So, the difference ...*" which does not matter in the context of the OP's example. – alk Aug 12 '16 at 10:03
  • 1
    @alk Very well, but there _maybe_ other usage and _this_ particular usage can be to keep the coding standard uniform for that project. Added the required disclaimer, though. ;) – Sourav Ghosh Aug 12 '16 at 10:06
6

Is &(*pVm) equivalent to pVm?

Yes. *1

Same for *(&pVm).


(*1) As the *-operator (de-referencing) only is applicable to pointers, the former construct only works on a pointer (or an array, which would decay to a pointer to its 1st element). The latter can be applied to any type of variable.:

alk
  • 69,737
  • 10
  • 105
  • 255
3

Yes, they are the same, but notice that it fails when the object is not an array or a pointer:

#include <stdio.h>

struct t {
    int value;
};

typedef struct t t;

int func(t *ptr)
{
    return ptr->value;
}

int main(void)
{
    t o = {.value = 0};
    t v[2] = {{.value = 1}, {.value = 2}};

    printf("%d\n", func(&(*o))); /* error: invalid type argument of unary ‘*’ */
    printf("%d\n", func(&(*v))); /* WORKS */
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94