Pimpl Idiom client/serve compile/link

This is a discussion on Pimpl Idiom client/serve compile/link within the C++ Programming forums, part of the General Programming Boards category; Hello everyone,
Suppose in Pimpl Idiom, we put private members into Pimpl class (implementation class).
( http://www.gotw.ca/gotw/024.htm )
My questions ...

Pimpl Idiom client/serve compile/link

My questions are, if we changed the Pimpl class and do not change visible parts of the whole component (class). There are two parties, component and client. Inside the component, there are two parts, Pimpl part and visible (to client) part.

1. For the component, I think it needs re-compile, since private members of Pimpl part changed are referred by visible parts (public members refer to private members);

2. I am not sure whether for the whole component, it needs to relink? I think it depends on whether other compile unit of the component invokes functions from the Pimpl part of component? Is it correct?

3. I am not sure whether for the client, it needs re-link? If we provide the whole component as a static lib, client needs to re-link, right? And if we provide the whole component as a DLL, and client implicit links with it with import library, does the client needs relink again?

1) Component needs to be recompiled.
2) Component needs to be relinked, of course. Otherwise you wouldn't get the new binary code into the thing. The implementations of the public part reside together with those of the private part. The point of PIMPL is that these implementations don't change and thus preserve binary compatibility.
3) Client doesn't need to recompile. It does need to relink against the new binary. Of course, if the component is in a DLL, relinking happens at load time anyway, so there's nothing to do.

I am confused, CornedBee. Do you mean when we call LoadLibrary, link.exe (MSVC linker program) will be invoked? In my previous understanding, if using LoadLibrary, only the address of exported function is retrieved by the loader when we call GetProcAddress.

Link.exe is not part of the load process, it's part of the build process for the executable file [e.g. DLL and EXE].

"The loader" is the part of the OS that loads an executable file, and it's dependant DLL portions into memory. This will include calling LoadLibrary [or it's internal counterpart(s) inside the kernel at least] to get the DLL loaded into the memory. This happens without the executable's code being run at all.

And yes, that's ALSO called linking (perhaps the terms Static and Dynamic linking can be used to differentiate the two).

Sorry I want to confirm with you (since it is the 1st time to learn and derive the concept of linking), you mean when we load a DLL using LoadLibrary, it is called dynamic linking and even if no link.exe is invoked?

Originally Posted by matsp

Link.exe is not part of the load process, it's part of the build process for the executable file [e.g. DLL and EXE].

"The loader" is the part of the OS that loads an executable file, and it's dependant DLL portions into memory. This will include calling LoadLibrary [or it's internal counterpart(s) inside the kernel at least] to get the DLL loaded into the memory. This happens without the executable's code being run at all.

And yes, that's ALSO called linking (perhaps the terms Static and Dynamic linking can be used to differentiate the two).

The process of matching one binary executable file with another binary executable file is called linking. The difference between Static and and Dynamic linking[1] is:
* Static linking is done immediately after producing the binary components, as part of the process to build the bindary executable file itself. This uses "link.exe" or something similar [e.g. gcc's "ld").

* Dynamic linking is done at load-time, when an application is started in the system. This involves the same functions as LoadLibrary performs, but not necessarily using EXACTLY LoadLibrary, connecting the imported functions in one component with the exports of another component. [E.g. the C runtime library will connect to CreateFile somwhere in the code for "fopen()"].

[1] Static and Dynamic linking is something I'm using here to clarify the situation, don't expect everyone around you to understand these names.

Your description is clear. From my original question, Pimpl pattern only saves time for the client to compile, not saving the time for component to compile/link and also not saving the time for client to link. Right?

From above point of view, Pimpl pattern does not save too much work of client and provide so magic and powerful functons. :-)

Any comments?

Originally Posted by matsp

The process of matching one binary executable file with another binary executable file is called linking. The difference between Static and and Dynamic linking[1] is:
* Static linking is done immediately after producing the binary components, as part of the process to build the bindary executable file itself. This uses "link.exe" or something similar [e.g. gcc's "ld").

* Dynamic linking is done at load-time, when an application is started in the system. This involves the same functions as LoadLibrary performs, but not necessarily using EXACTLY LoadLibrary, connecting the imported functions in one component with the exports of another component. [E.g. the C runtime library will connect to CreateFile somwhere in the code for "fopen()"].

[1] Static and Dynamic linking is something I'm using here to clarify the situation, don't expect everyone around you to understand these names.

The reason for using "pimpl" is more to do with "binary compatibility" than with actually reducing compile/link time. The point is that the interface to the public portion stays the same whatever the implementation "behind the scenes" is. This means that there is no changes to the code using the outer interface, and thus an executable that uses the outer interface (that is, the client) doesn't need to be recompiled. It still needs to link, either statically or dynamically to the new "behind the scense" code.

Since the component "pimpl" is a pointer, it doesn't change size when the implementation changes. Consider for example that we have a container class specifically to store and retrieve C identifiers.

If we now have a brilliant idea of storing the data in a different way [e.g. a binary tree, hash-table or some other "better" data format], then we would have to recompile ANY code that uses this class.

The reason for using "pimpl" is more to do with "binary compatibility" than with actually reducing compile/link time. The point is that the interface to the public portion stays the same whatever the implementation "behind the scenes" is. This means that there is no changes to the code using the outer interface, and thus an executable that uses the outer interface (that is, the client) doesn't need to be recompiled. It still needs to link, either statically or dynamically to the new "behind the scense" code.

Since the component "pimpl" is a pointer, it doesn't change size when the implementation changes. Consider for example that we have a container class specifically to store and retrieve C identifiers.

If we now have a brilliant idea of storing the data in a different way [e.g. a binary tree, hash-table or some other "better" data format], then we would have to recompile ANY code that uses this class.