Passing by reference - is it identical to passing a pointer?

I have read more than once that passing by reference is just passing a pointer that is automatically dereferenced inside a function. How true is this?

For example, I wrote such a dll (in Visual Studio):

extern "C"
void __declspec(dllexport) test(int* i)
{
    cout << "test(" << *i << ")\n";
    (*i)++;
}

And here is a program to work with it:

typedef void (*myfunc)(int&);
int main()
{
    HMODULE dll;
    if ((dll = LoadLibrary("Dll.dll")) != NULL)
    {
        myfunc f = (myfunc)GetProcAddress(dll,"test");
        int q = 5;
        cout << "q = " << q << endl;
        f(q);
        cout << "q = " << q << endl;
        FreeLibrary(dll);
    }
}

Everything works, it turns out that I wanted it:

q = 5
test(5)
q = 6

Only how much can this transfer by reference as a pointer be relied on? What kind of trouble could there be?

And again immediately I wanted to ask, do I, for example, use cout in the dll - is it the same cout as in the main program or not? And if I pass a pointer to it , then the code in the dll will still be used, and not in the program? Or if I allocate memory in the dll, how do I properly release it in the program? for example, if I return unique_ptr to a function in a dll?

Author: Harry, 2017-03-07

3 answers

No, it is not identical.

A pointer is a physical object in memory that occupies space and has a value.

A reference is simply a synonym for the name of an object, for which no additional memory is allocated.

In other words, when you operate with references, you can imagine that you are working with the same variable as when declaring it (for the compiler, there is no difference in this case).


In case of use dynamic-link libraries, the strict recommendation is to use From the interface (only pointers exist in C), in order to be able to work with the library from other languages. Do not return std::unique_ptrin this case.

Also about memory allocation, if you allocate memory inside the library, then inside and should release.

The use of smart pointers in this case is a modern approach to tracking data. memory. Try to strictly avoid explicit calls to delete.

First of all, you should decide whether you really need to allocate memory inside the library or whether it is acceptable to transfer the buffer and its size to it.


If the library still needs to allocate memory and return it, then let's say we have two functions:

void* dll_alloc(size_t size) and dll_free(void* ptr)

Then for convenient operation and automatic memory release, we can use the following:

std::shared_ptr<void> dllMemory(dll_alloc(1024), dll_free);

In that case, we don't need to explicitly call dll_free.

 3
Author: sever2715, 2017-03-07 14:17:42

You have no right to assume that the reference inside is arranged as a pointer. A function declaration that differs from its present definition is an undefined behavior.

That it "works" is a fluke, as with any UB. With the complication of the program and / or changing the compiler settings, any unpleasant surprises are possible.


What is true in the words you have quoted is that the reference behaves much like an automatically dereferenced one the pointer.

An important semantic difference between a pointer and a reference is that a reference cannot be reassigned, and it must point to some object (in a valid program). That is, there are no "null references".

 6
Author: VladD, 2017-03-07 07:43:11

For the first part - I think that there are no instructions in the standard and there should not be. Frankly speaking, I don't think that if such a transfer to VC++ is successful, then at some point it will cease to be so... but I fully admit that another compiler may work differently. Therefore, it seems to me that within a single compiler-roughly speaking, in your own program-you can use it in principle... being aware that, in theory, this may break down in some future versions.

But isn't it easier to use an extra level of indirection? Just write a proxy function that accepts a reference, but calls a DLL function with the address of that reference passed to it?

On the second part - if you used static libraries, then yes, cout you have different ones, if the dynamic runtime is the same, I think, from dynamic libraries.

About memory - as far as I remember the advice of experienced:), it is highly desirable to free up memory where it was selected. But how to coordinate the same smart pointers or something else with this-a simple and reliable way does not come to mind yet.

 4
Author: Harry, 2017-03-07 08:11:21