They are not operations, except that they can cause compile-time errors. Therefore, they can be useful in the macro as a statement. *&l
guarantees that it l
is an lvalue, but &*p
guarantees that the p
(implicitly convertible) pointer.
#define ASSERT_LVALUE(l) (void)(*&(l))
#define ASSERT_POINTER(p) (void)(&*(p))
int main(void) {
int* p;
int i;
ASSERT_LVALUE(i);
ASSERT_LVALUE(3);
ASSERT_POINTER(p);
ASSERT_POINTER(i);
ASSERT_POINTER(3);
return 0;
}
source
share