7

编辑:我知道包含警卫,但包含文件不是这里的问题。我说的是实际编译并已链接到静态库中的代码。

我正在用 C++ 为自己创建一个通用实用程序库。

我正在创建的函数之一,printFile, requires stringcout以及标准库的其他此类成员。

我担心当库被编译,然后链接到另一个也使用stringand的项目时,和cout的代码将被复制:它都将在程序链接的库二进制文件中预先链接,并且它将是再次与使用它们本身的项目相关联。stringcout

该库的结构如下:

  1. libname.hpp使用该库的程序员应该#include在他的项目中使用一个文件。
  2. fname对于在 中声明的每个函数libname.hpp,都有一个fname.cpp实现它的文件。
  3. 所有fname.cpp文件也#include "libname.hpp".
  4. 库本身编译成libname.a复制到/usr/lib/.

这甚至会发生吗?
如果是,这是否有问题?
如果是,那么我该如何避免这种情况?

4

4 回答 4

3

我担心当编译库,然后链接到另一个也使用字符串和 cout 的项目时,字符串和 cout 的代码会重复

别担心:没有现代编译系统可以做到这一点。模板函数的代码被发送到目标文件中,但链接器会丢弃重复的条目。

于 2012-12-31T02:05:22.013 回答
3

标准 C++ 库的库定义不会出现在您自己的静态库中,除非您在其中明确包含它们(即,您从标准 C++ 库中提取目标文件并将它们包含到您的库中)。静态库根本没有链接,只会对其他库有未定义的引用。静态库只是定义库提供的符号的目标文件的集合。来自标题的定义,例如内联函数和模板实例化,将以这样一种方式定义,即多个翻译单元中的多个定义不会发生冲突。如果代码实际上没有内联,它将定义“弱”符号,导致在链接时忽略或删除重复项。

唯一真正关心的是链接到可执行文件的库需要使用兼容的库定义。由于头文件中有大量代码,因此 C++ 头文件的更改相对频繁,包括标准 C++ 库头文件(相对于包含更少代码的 C 库头文件)。

于 2012-12-31T02:10:36.620 回答
0

是的,标准库的代码将被复制。例如,如果您返回 std::string 或在其中一种方法中将其作为参数,则可能会出现问题。它在您的标准库实现中的布局可能与用户的不同。

于 2012-12-31T02:03:43.933 回答
0

这在实践中很少出现问题。

对于static头文件中定义的函数和内联模板函数,无需担心:每个编译单元都有自己的副本(例如,在.a库中可能已经有许多匿名副本)。这没关系,因为这些定义没有被导出,所以链接器不需要担心它们。

对于使用非静态链接声明的函数,是否有问题取决于链接.a库的方式。

构建库时,通常不会在标准 C++ 库中进行链接。创建的库将包含对标准 C++ 库的未定义引用。这些必须在构建最终的可执行二进制文件之前解决。这通常在以默认方式链接最终二进制文件时自动完成(取决于编译器)。

There are times when people do link in the standard C++ library into a static library. If you're linking against multiple static libraries that each embed another library (like the standard C++ library), then expect trouble if there are any differences in those embedded libraries. Fortunately, this is a rare problem, at least with the gcc toolchain. It's a more frequent problem with Microsoft's tools.

In some cases, a workaround is to make one or more conflicting static libraries into a dynamic library. This way each of these dynamic libraries can statically link its own copy of the problematic library. As long as the dynamic library doesn't export the symbols from the problematic library and there are no memory layout incompatibilities, there generally isn't any trouble.

于 2012-12-31T03:54:57.533 回答