动态库是否违反C++标准

Do dynamic libraries break C++ standard?

本文关键字:C++ 标准 是否 动态      更新时间:2023-10-16

C++标准3.6.3规定

静态持续时间的初始化对象的析构函数是从main返回和调用exit的结果

在windows上,您有FreeLibrary,在linux上,您可以dlclose卸载动态链接库。您可以在从main返回之前调用这些函数。

卸载共享库的副作用是运行库中定义的静态对象的所有析构函数。

这是否意味着它违反了C++标准,因为这些析构函数过早地运行了

这是一个毫无意义的问题。C++标准没有说明dlclose做什么或应该做什么。

如果该标准包含dlclose的规范,那么它肯定会指出dlclose是3.6.3的例外。因此,3.6.3不会被违反,因为它将是一个记录在案的例外。但我们不能知道,因为它不包括它。

dlclose对C++标准中的保证的影响完全超出了该标准的范围。dlclose所能做的任何事情都不会违反C++标准,因为该标准对此只字未提

(如果这是在程序没有做任何特定调用的情况下发生的,那么你就会有一个合理的理由认为违反了标准。(

Parapura,请记住C++标准是一种语言定义,它对编译器如何将源代码转换为目标代码施加了限制。

该标准不对操作系统、硬件或任何其他方面施加约束。

如果用户关闭了他的机器,这是否违反了C++标准?当然不是。标准是否需要将"除非用户关闭设备"作为每条规则的"例外"?那太傻了。

类似地,如果一个操作系统杀死了一个进程或强制释放了一些系统资源,甚至允许第三方程序破坏你的数据结构,这并不违反C++标准。这很可能是操作系统中的一个错误,但C++语言的定义仍然完好无损。

该标准仅对编译器具有约束力,并强制生成的可执行代码具有某些属性。尽管如此,它并没有绑定运行时行为,这就是为什么我们在异常处理上花费了这么多时间。

我认为这是一个开放式的问题。

我想说是这样的:标准只定义程序是什么。程序(我应该补充一下,"托管"程序(是一个编译和链接的翻译单元的集合,它有一个唯一的main入口点。

共享库没有这样的东西,所以它甚至不构成标准意义上的"程序"。它只是一堆链接的可执行代码,没有任何"流"。如果使用加载时链接,库将成为程序的一部分,一切都如预期。但是,如果使用运行时链接,情况就不同了。

因此,您可能喜欢这样看待它:运行时链接共享对象中的全局变量本质上是由动态加载器构建的动态对象,并且在卸载库时被销毁。这些对象被声明为全局对象这一事实并没有改变这一点,因为在这一点上,这些对象不是"程序"的一部分。

只有在您付出巨大努力的情况下,它们才会过早运行-默认行为符合标准。

如果它确实违反了标准,谁是违规者?C++编译器不能被视为违规者(因为事情是通过库调用动态加载的(;因此它必须是动态加载功能的供应商,也就是操作系统供应商。操作系统供应商在设计系统时是否受C++标准的约束?这显然超出了标准的范围。

或者从另一个角度来看,可以将库本身视为一个单独的程序,提供某种服务。当这个程序终止时(无论以何种方式卸载库(,所有相关的服务对象也应该消失,无论是静态的还是非静态的。

这只是可用的大量特定于平台的"扩展"之一(用于目标编译器、体系结构、操作系统等(。所有这些都以各种方式"违反"了标准。但是,偏离标准C++的预期结果只有一个:您不再是可移植的了。(除非你做了很多#ifdef之类的事情,但那个特定的代码仍然被锁定在那个平台上(。

由于目前还没有标准/跨平台的库概念,如果你想要这个功能,你必须不使用它,或者按照每个平台重新实现它。由于类似的东西出现在大多数平台上,也许有一天标准会找到一种干净的方法来抽象它们,从而使标准涵盖它们。其优点将是跨平台解决方案,它将简化跨平台代码。