Search code examples
c++assembly

C++ Is there any two function which don't gives same assembly code when compiled with -O3 one with pointer and other one with reference paramaters


I wanted to understand references better so I played with some C++ code to see diffrence between references and pointers, when they compiled to assembly (-O3) I realized they both give the same assembly code.

I am curious about is there any function which gives diffrent assembly code when we use references instead of pointers as parameter.

Its more easy to understand with example: (I used godbolt to see assembly outputs.)

struct someStruct
{
    int a;
    int* ptr;
    someStruct* next;
};
int f1(someStruct* v)
{
    v->a = v->next->a + *v->next->ptr;
    v->ptr = v->next->ptr;
    v->next = v;
    return v->a;
}
int f1(someStruct& v)
{
    v.a = v.next->a + *v.next->ptr;
    v.ptr = v.next->ptr;
    v.next = &v;
    return v.a;
}

This two functions both give this same Assembly x86 code:

f1(someS*):                           # @f1(someS*)
        mov     rcx, qword ptr [rdi + 16]
        mov     rdx, qword ptr [rcx + 8]
        mov     eax, dword ptr [rdx]
        add     eax, dword ptr [rcx]
        mov     dword ptr [rdi], eax
        mov     qword ptr [rdi + 8], rdx
        mov     qword ptr [rdi + 16], rdi
        ret

Solution

  • bool f(int& x) { return &x != nullptr; }
    bool g(int* x) { return x != nullptr; }
    

    The first function must always return true because a reference must always be bound to an object. A pointer to an object (formed with &x) has never a null pointer value.

    A pointer variable on the other hand can have a null pointer value as well and so g may or may not return true.

    Compilers (probably at any non-zero optimization level) are aware of this difference between references and pointers and therefore will optimize f to return true independent of the argument, while g will contain an actual test of the condition.