Search code examples
c++pointersreferencepass-by-referenceauto

Is there any point of "reference of pointer"?


I can't understand how reference of pointer type works.

  1. Is there any performance difference?

  2. Is there any assembly level difference if they compiled?

  3. Is there any point to reference of pointer type?

vector<Figure*> vFigureList;

//auto&
for(auto& pFigure : vFigureList)
{
    pFigure->draw();
    delete pFigure;
}

//auto
for(auto pFigure : vFigureList)
{
    pFigure->draw();
    delete pFigure;
}

//Figure*
for(Figure* pFigure : vFigureList)
{
    pFigure->draw();
    delete pFigure;
}

//Figure*&
for(Figure*& pFigure : vFigureList)
{
    pFigure->draw();
    delete pFigure;
}

Solution

  • Once compiled, references are just like pointers, they provide a level of indirection. However they have different use in C++:

    • They must be initialized upon definition, hence safer, like a const pointer.
    • No need to use the address of & operator to declare where they point to.
    • No need to deference using *.

    Is there any performance difference?

    Yes, references incur a level of pointer dereference, just like a normal pointer.

    Is there any assembly level difference if they compiled?

    Compared to a plain variable, yes, an extra level of indirection. Compared to a pointer, no, references and pointers are the same once compiled.

    Is there any point to reference of pointer type?

    Yes, if you needed a pointer to a pointer, but wanted the safety and convenience of a reference.

    Here's an example on Compiler Explorer (same source below in case link expires): https://godbolt.org/z/h3WzdPWa1

    When compiled with no optimization (not recommended, just for illustration with this Compiler Explorer example):

    • Direct access uses three assembly instructions
    • One level of indirection (pointers and references) uses five instructions
    • Two levels of indirection (reference to pointer and pointer to pointer) uses seven instructions

    This helps illustrate that references are really pointers under the hood, with the same performance implications.

    int num();
    int* num_ptr();
    
    int main() {
        int i = num();
        
        int& r = i;
        int* p = num_ptr();
    
        int*& pr = p;
        int** pp = &p;
    
        // Direct access
        i += 3;
    
        // One level of indirection
        r += 5;   
        *p += 7;
    
        // Two levels of indirection
        *pr += 11;
        **pp += 13;
    
        return 0;
    }