1

I'd like to explore the feats of pointer with the following codes:

#include <stdio.h>
int x = 3;
int main(void)
{
    printf("x's value is %d, x's address is %p", x, &x);
    //printf("x's address is stored in", &&x);
}

It works properly and get outputs

$ ./a.out
x's value is 3, x's address is 0x10b1a6018

When I utilize &x, a memory space is set aside for it to keep the address 0x10b1a6018, so an address is printed.

Sequently, I intent to get info about the address which store another address.

#include <stdio.h>
int x = 3;
int main(void)
{
    printf("x's value is %d, x's address is %p", x, &x);
    printf("x's address is stored in", &&x);
}

But it report error as:

$ cc first_c_program.c 
first_c_program.c:14:40: warning: data argument not used by format string [-Wformat-extra-args]
    printf("x's address is stored in", &&x);
           ~~~~~~~~~~~~~~~~~~~~~~~~~~  ^
first_c_program.c:14:42: error: use of undeclared label 'x'
    printf("x's address is stored in", &&x);
                                         ^
1 warning and 1 error generated.

How could I retrieve information about the memory address which store the address of value x.

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138
  • 2
    "When I utilize &x, a memory space is set aside for it " No, there is no memory reserved to store that address. It is only temporarily evaluated and passed to `printf`. This might be in a register. You cannot get the address of this value. – Gerhardh Oct 19 '18 at 07:53
  • I love your comment "This might be in a register", cos, it should not be a ghost. @Gerhardh, could you please transmit it to answer. – AbstProcDo Oct 19 '18 at 08:03
  • I guess C standard should claim, variable as direct variable, pointer as indirect variable to eliminate the confusions for the newbie. – AbstProcDo Oct 19 '18 at 08:29

3 Answers3

5

&x is a temporary value. It is not stored in memory and does not have an address.

Similarly &42 is invalid because 42 is not stored in memory (it's also a temporary value).

The slightly weird error message you get is because gcc implements a unary && operator, which can be used to get the address of a label. This is a non-standard extension of the C language.

To get a better error message, use & &x (with a space) or &(&x).

But what you want simply doesn't exist.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 1
    much better now , `first_c_program.c:14:43: error: cannot take the address of an rvalue of type 'int *'`, thank you. – AbstProcDo Oct 19 '18 at 08:24
4

&x is a non-lvalue expression. It does not have a location. & requires an lvalue as its operand (or a function).

&&x is not a valid construct at all in standard C. The address is not necessarily stored anywhere at all - in your program as x is a global variable, it is a compile/link-time constant!


Instead GCC uses unary &&x as an extension to get the address of jump label x for computed goto. This does not break C conformance by itself as && is parsed as a single token and && is not allowed as an unary operator in standard C.

I.e. you can write

    static void *array[] = { &&foo, &&bar, &&hack };

    int i = 1;
    goto *array[i]; // jump to label bar

    ...

foo: ...
bar: ...
baz: ...
1

To do what you want, you need to store &x in a variable:

int* y = &x;
printf("%p", &y);
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268