tags:

views:

221

answers:

3

I have seen this in our code a couple times and it immediately makes me suspicious. But since I don't know the original intent I am hesitant to remove it.

//requires double indirection which I won't go into
FooClass::FooFunction(void ** param)
{
  //do something
}

SomeClass * A = new SomeClass();
SomeClass **B = &A;
FooFunction( reinterpret_cast<void**>(&*B) );   // what is happening here?

The "&*B" part is the part in question? Feel free to integrate explanation of the reinterpret cast but I am pretty familiar with cast techniques.

+10  A: 

I've done similar things with iterators - dereference the iterator to get a reference, and then do the "&" operator to get a pointer.

I don't see why it would be doing anything here though. If the type to the right of "&*" is a pointer type it does nothing.

Greg Rogers
+2  A: 

Consider the following sample;

class A {
public:
    int f() { return 55; }
};

class B {
public:
    B( A* a ) : a(a) {}
    A*& operator*() { return a; }

    A* a;
};

int main () {
    A* a = new A();
    B b = a;

    // &* calls operator*, then gets address of A
    void** x = reinterpret_cast<void**>(&*b);
    cout << reinterpret_cast<A*>( *x )->f() << endl; // prints 55

    void** x2 = reinterpret_cast<void**>( b );       // compile error
}

Your last edit of question leads to:

A* a = new A();
A** b = &a;

void** x = reinterpret_cast<void**>(&*b);  // now this is equal to the following
void** x2 = reinterpret_cast<void**>( b ); // so using &* make no sense
Kirill V. Lyadvinsky
David Thornley
If `A` is a straight pointer here, then OP's question has no sense.
Kirill V. Lyadvinsky
BuckFilledPlatypus
Changed sample to remove misunderstanding with `shared_ptr`. That was not really good sample.
Kirill V. Lyadvinsky
B is just an simulation of smart pointer.
Kirill V. Lyadvinsky
+3  A: 

I can see only one reason for this: B has overloaded operator*() to return an X, but whoever wrote the code needed an X*. (Note that in your code, X is A*.) The typical case for this is smart pointers and iterators.

If the above isn't the case, maybe the code was written to be generic enough to deal with smart pointers/iterators. Or it used to use smart pointers and whoever changed it didn't bother changing &*, too? Have you poked through its history to see when this was introduced and what the code looked then?

sbi
@sbi, so in this case would it be pointless to just use reinterpret_cast<void**>(B) ? I am unaware of an overloaded * operator for this particular ptr, so it seems like we are getting a temporary ptr back for something for which we already have double indirection?
BuckFilledPlatypus
If `B` is indeed a naked pointer (of type `SomeClass**`) as shown in your question, the it's certainly pointless. (But it doesn't hurt either.)
sbi
Ok, that answers the question then. If it is not some special case then it is indeed pointless as I am suspecting.
BuckFilledPlatypus