sky*_*ack 19 c++ shared-libraries language-lawyer c++17 inline-variable
这是对这个问题的跟进.
如答案评论中所述:
内联变量具有以下属性: - 在每个转换单元中具有相同的地址.[...]通常您通过在cpp文件中定义变量来实现这一点,但是使用内联说明符,您只需在头文件中声明/定义变量,并且使用此内联变量的每个转换单元都使用完全相同的对象.
而且,从答案本身来说:
虽然该语言不保证(甚至提及)在跨共享库边界使用此新功能时会发生什么,但它确实可以在我的计算机上运行.
换句话说,当涉及共享库时,不清楚内联变量是否保证跨边界是唯一的.有人在经验证明它可以在某些平台上运行,但它不是一个正确的答案,它可能只是破坏其他平台上的一切.
内联变量在跨越边界使用时是否有任何保证,或者它只是一个我不应该依赖的实现细节?
这就是我解释标准的方式.根据basic.link/1:
程序由一个或多个链接在一起的翻译单元组成.
它没有说静态链接和动态链接.程序是链接在一起的翻译单元.如果链接分两步完成并不重要(首先创建.dll/.so,然后动态链接器将所有动态库+可执行文件链接在一起).
因此,在我的解释中,程序是动态链接还是静态链接并不重要,实现应该表现相同:类静态变量应该是唯一的(无论它是否内联).
在Linux上,这是事实.
在Windows上,这并不适用于所有情况,因此在我的解释中,它在这些情况下违反了标准(如果您创建一个单独的.dll,其中包含静态非内联变量,以及所有其他.dll和exe引用此变量,它起作用).
C ++当前没有共享库的概念。因此,inline跨共享库的行为方式将是特定于实现和平台的。
这一事实[basic.link] / 1规定,“ 程序是由连在一起的一个或多个翻译单元。 ”不颇有意思的是一个程序链接与其他一起,已经链接模块,应该具有相同的行为。
多年来,已经提交了许多建议来纠正这种情况(N1400,N1418,N1496,N1976,N2407,N3347,N4028),但没有一个起步。用通用的方法很难实现,而C ++通常会尽量避免实现细节。正如海湾合作委员会所说:
对于既不支持COMDAT也不支持弱符号的目标,大多数具有模糊链接的实体都作为本地符号发出,以避免链接程序重复定义错误。对于内联的局部静态函数,这不会发生,但是,拥有多个副本几乎肯定会破坏事情。
默认情况下,MSVC不公开任何符号。任何“外部”符号都需要使用特定于平台的显式声明__declspec(dllexport)。因此,不能说Windows与C ++不兼容。这里没有违反C ++规则,因为没有任何规则。
| 归档时间: |
|
| 查看次数: |
724 次 |
| 最近记录: |