C++ 标准对动态库有什么看法?

What does C++ standard say about dynamic libraries?

提问人:blonded04 提问时间:11/9/2023 最后编辑:HolyBlackCatblonded04 更新时间:11/11/2023 访问量:150

问:

C++ 标准对动态库有什么看法?我听说它完全忽略了它们(出于某种原因)——如果这是真的,为什么会这样?

C++ 链接动态

评论

6赞 Adrian Mole 11/9/2023
动态库在 C++ 标准解决的“抽象机器”上会是什么样子?
3赞 HolyBlackCat 11/9/2023
删除了,因为您正在寻找解释,而不是标准报价。language-lawyer
3赞 prapin 11/9/2023
我并不是C++标准的专家,但我猜该标准同样忽略了静态库,目标文件,可执行文件,甚至源文件等概念,因为它旨在足够抽象。
6赞 Richard Critten 11/9/2023
C++ 标准草案 [intro.abstract] “...相反,需要符合要求的实现来模拟(仅)抽象机器的可观察行为,如下所述......”
4赞 Peter 11/9/2023
C++ 标准指定了抽象机器,以及如何诊断或转换 C++ 代码(包括语言结构和库功能)以产生该抽象机器的可观察行为。该标准没有指定实现(例如编译器和标准库的相关实现)如何在代码和实际目标机器的可观察行为之间执行转换。动态库不是抽象机器的一部分,也不需要由实现(编译器、主机平台等)支持。

答:

4赞 Ext3h 11/9/2023 #1

实际上,动态库只有 2 个主要陷阱,您可以在其中轻松打破 C++ 标准中所做的假设,使其与抽象机器不匹配:

  • 违反“一个定义”规则:例如,您设法将两个库与同一符号的不同实现动态链接;出于某种原因,每个链接都首选本地链接,并且根据调用者的不同,使用不同的实现。C++ 规范仍然告诉你允许你做什么,即使编译器、链接器和动态加载器可以很容易地配置为违反该规则。

    在这种情况下,例如,在 Linux 系统上,具有所有符号的公共可见性,这意味着所有符号都由动态加载器在运行时解析,这实际上符合抽象机器的描述。ld-linux + gcc + ld

    不幸的是,出于性能原因,此默认值根本不可取。限制符号的可见性是允许最基本的内联优化形式的先决条件。

  • 在意外时间加载和卸载库:这意味着指针(指向代码和数据段)可能会在任意时间变得(或保持)无效,这与抽象状态机完全不匹配。

在这两种情况下,作为开发人员,您仍然有责任确保保持在抽象机器的范围内,并且不会导致任何与抽象机器相矛盾的可观察行为。

理论就这么多。

现实情况是,在这两种情况下,大多数动态库实际上甚至没有尝试将系统/进程作为一个整体与 C++ 抽象机器兼容。

相反,C++ 只期望在每个动态库完全正常运行,而整个外部接口完全了解动态链接、符号可见性等,并避免任何可能在边界上暴露未定义行为的 C++ 功能。每个库 - 单独 - 都与抽象机器保持一致。