В библиотеке unqlite c я нашел следующий код:
pObj = jx9VmReserveMemObj(&(*pVm),&nIdx);
где pVm
:
typedef struct jx9_vm jx9_vm; jx9_vm *pVm
и вызванная функция объявляется как:
jx9_value * jx9VmReserveMemObj(jx9_vm *, sxu32 *);
Что для конструкции &(*pVm)
используется в вызове вместо простого pVm
? Is &(*pVm)
эквивалентно pVm
?
Цитирование C11
, глава §6.5.3.2, Операторы адреса и косвенности
[…] Если операнд является результатом унарного
*
оператора, ни этот оператор, ни оператор&
не оцениваются, и результат как бы опускался , за исключением того, что ограничения на операторы все еще применяются, а результат не является lvalue. […]
Итак, да , они эквивалентны .
Однако эту конструкцию можно использовать для проверки типа аргумента на тип указателя. Из свойства унарного оператора *
Операнд унарного
*
оператора должен иметь тип указателя.
Итак, конструкция &(*pVm)
pvm
– имя указателя или массива. pvm
является переменной типа не указателя. См. Другой ответ Alter Mann для примера кода.
Еще одна разница ( в общем случае ), pVm
может быть назначена (может использоваться как LHS оператора присваивания), но &(*pVm)
не может.
Is
&(*pVm)
эквивалентноpVm
?
Да. * 1
То же самое для *(&pVm)
.
(* 1) Так как *
-оператор ( de-referencing ) применим только к указателям, первая конструкция работает только с указателем (или массивом, который распадается на указатель на его 1-й элемент). Последнее может применяться к любому типу переменной. :
Да, они одинаковы, но заметьте, что это не удается, когда объект не является массивом или указателем:
#include struct t { int value; }; typedef struct tt; int func(t *ptr) { return ptr->value; } int main(void) { to = {.value = 0}; tv[2] = {{.value = 1}, {.value = 2}}; printf("%d\n", func(&(*o))); /* error: invalid type argument of unary '*' */ printf("%d\n", func(&(*v))); /* WORKS */ return 0; }