int main(int argc, char * argv[]) {
int a = 10;
int * sp = &a;
int * * dp1 = &sp;
int * * dp2 = &&a; // NG
int * * dp3 = &(&a); // NG
int * * dp4 = &((int *) &a); // NG
}
$ cc test.c
test.c: In function ‘main’:
test.c:6:17: error: lvalue required as unary ‘&’ operand
int * * dp3 = &(&a); // NG
^
test.c:7:17: error: lvalue required as unary ‘&’ operand
int * * dp4 = &((int *) &a); // NG
^
test.c:5:3: error: label ‘a’ used but not defined
int * * dp2 = &&a; // NG
^
Why can't I use
&&a
Because &
gives you the address of a varibale and &a
is not a variable.
The C 11 Draft specifies the following:
6.5.3.2 Address and indirection operators
Constraints
1 The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.
[...]
Semantics
3 The unary & operator yields the address of its operand. [...]
To get around this "limitation" one could introduce temporary storage using a compound literal like this (assuming C99 at least):
int a = 42;
int ** ppa = &((int *){&a});
As a side note referring to the error message below:
test.c:5:3: error: label ‘a’ used but not defined
int * * dp2 = &&a; // NG
^
gcc (and probably others) define an extension to the C-Standard allowing the use of the &&
operator on a single operant if the operant identifies a label. (More on this here: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html)
Example:
void * pv = &&lbl;
goto *pv;
/* some dead code */
lbl:;
/* living code again here */