Dereferencing a Pointer to an int Through a Pointer to a Member

closed account (zb0S216C)
This is hard for me to explain, so I'll try my best. I'm trying to dereference a pointer through a pointer to a member. This is the class:

1
2
3
4
struct Test
{
    int *member;
} n;

...and this is main():

1
2
3
4
5
6
int main()
{
    int *(Test:: *p)(&Test::member);

    return(0);
}

How do I dereference Test::member through p?

Wazzak
*(n.*p)
Is this what you mean?
Last edited on
closed account (zb0S216C)
That's it! Thanks LB & Cubbi, I appreciate it :)

One more question, how is the expression evaluated?

Wazzak
Last edited on
Thank Cubbi too, he posted just seconds after me then deleted his post. ;)
EDIT: And JLBorges too, apparently. This thread is hopping!
Last edited on
Thank Cubbi too, he posted just seconds after me then deleted his post. ;)

It's a stackoverflow habit, avoiding duplicate answers.
how is the expression evaluated?
warning: unnecessary details follow

1. The subexpression 'n' is evaluated. It results in lvalue Test

2. The subexpression 'p' is evaluated. It results in lvalue pointer-to-member-of-Test

3. lvalue-to-rvalue implicit conversion is applied to the result of 2, this reads the value of the pointer (from RAM to CPU, essentially)

4. operator .* is evaluated. It results in lvalue int* (it always returns the value category of its left operand) which identifies the actual member subobject of n

5. lvalue-to-rvalue implicit conversion is applied to the result of 4, this reads the value of the member subobject (e.g. the address stored in that pointer is loaded from RAM to CPU)

6. operator* is evaluated: it identifies the object stored at the address that was obtained in 5. The result is an lvalue of type int which identifies the pointed-to integer.

My numbering does not reflect the order of evaluation: 1 can happen after 2 or after 3 (but always before 4)
Last edited on
Oh, and so you know what those scary words become in code, this is what GCC does to the expression

cout << *(n.*p);

1
2
3
4
        movq    p(%rip), %rax     # 2,3
        movq    n(%rax), %rax     # 1,4,5
        movl    (%rax), %esi      # 6 and another lvalue-to-rvalue 
        call    std::ostream::operator<<(int)
Last edited on
closed account (zb0S216C)
Thanks, Cubbi :)

Maybe you can help me with something quick. I'm seeing what is and isn't possible with pointers-to-members. So I tried a pointer-to-a-member-pointer-to-a-function. That didn't go so well; I got the syntax wrong. I initially thought it would be this:

<TYPE>(*<PP_ID>)(<ARGS>) (<CLASS_ID>:: *<P_ID>)(&<CLASS_ID>::<FPTR_ID>);

1
2
3
4
5
6
7
8
9
10
11
12
struct Test
{
    void(*func)();
} n;

void extn() { }

int main()
{
    void(*F)() (Test:: *pF)(&Test::func); // Nope!
    return(0);
}

But it's not. Any idea how to declare it?

Wazzak
1
2
    void (*Test::*pF)() = &Test::func;
    (n.*pF)();

demo: http://ideone.com/IJZ0e
closed account (zb0S216C)
Cheers, Cubbi! Life-saver :)

Wazzak
Topic archived. No new replies allowed.