How to avoid including the same code when using C ++ libraries?

EDIT: I know about enabling guards, but not including files. I am talking about the actual compiled and already linked code that is baked into a static library.

I create a universal utility library for myself in C ++.

One of the printFile functions that I printFile requires string , cout and other such elements of the standard library.

I'm worried that when the library is compiled and then linked to another project that also uses string and cout , the code for string and cout will be duplicated: it will be prelinked in the binary library, the program will be linked to it, and it will be linked back to the project, which uses them myself.

The library is structured as follows:

  • There is one libname.hpp file that a programmer who uses the library must #include in his projects.
  • For each fname function declared in libname.hpp , there is a fname.cpp file that implements it.
  • All fname.cpp files are also #include "libname.hpp" .
  • The library itself is compiled into libname.a , which is copied to /usr/lib/ .

Is this really going to happen?

If so, is this a problem at all?

If so, how can I avoid this?

+7
source share
4 answers

I'm worried that when the library is compiled and then linked to another project that also uses string and cout, the code for the string and cout will be duplicated

Donโ€™t worry: no modern compilation system will do this. Code for template functions is emitted into object files, but the linker discards duplicate entries.

+3
source

The library definitions of the C ++ standard library will not be displayed in your own static library unless you explicitly include them there (i.e. you extract the object files from the C ++ standard library and include them in your library). Static libraries are not linked at all and will have undefined references to other libraries. A static library is simply a collection of object files defining the symbols provided by the library. Definitions that come from headers, such as built-in functions and template instances, will be defined in such a way that multiple definitions in multiple translation units do not conflict. If the code is not actually inlined, it will detect โ€œweakโ€ characters that lead to ignoring or removing duplicates during the link.

The only real problem is that libraries associated with the executable must use compatible library definitions. With a significant amount of code stored in header files, changes are relatively often made to C ++ header files, including standard C ++ library headers (relative to C library headers, which contain much less code).

+3
source

Yes, the code for standard library objects will be duplicated. This can be a problem if you return std :: string or use one of the parameters in one of your methods. It may have a different layout in your standard library implementation than in a custom one.

0
source

This is rarely a problem in practice.

There is nothing to worry about for the static functions and the built-in template functions defined in the header files: each compilation module gets its own copy (for example, in the .a library, there may already be many anonymous copies). This is normal because these definitions are not exported, so the linker does not need to worry about them.

For functions declared with non-static binding, whether your problem depends on how you link the .a library.

When you create a library, you usually will not be referenced in the C ++ standard library. The created library will contain undefined references to the standard C ++ library. They must be resolved before the final binary executable is created. This is usually done automatically when linking this final binary to the default (depending on the compiler).

There are times when people refer to a static library in the C ++ standard library. If you link several static libraries, each of which embeds a different library (for example, the standard C ++ library), then expect problems if there are any differences in these built-in libraries. Fortunately, this is a rare issue, at least with the gcc . This is a more common problem with Microsoft tools.

In some cases, a workaround is to create one or more conflicting static libraries in a dynamic library. Thus, each of these dynamic libraries can statically link its own copy of the problem library. As long as the dynamic library does not export characters from the problem library, and there is no incompatibility of the memory layout, there are generally no problems.

0
source

All Articles