【发布时间】:2020-01-21 16:44:59
【问题描述】:
前段时间I had asked 向共享库的struct 添加字段是否需要根据语义版本控制对版本字符串进行重大或次要更改。少数参与者倾向于提出重大改变。
几个月过去了,我还没有向我的struct 添加任何字段。但现在可能正是这样做的好时机。
但与此同时,我也一直在思考这会如何破坏使用我的库以前版本编译的程序的二进制兼容性,老实说,就我所想的而言,我还没有发现任何可能的二进制兼容性情况休息。
新字段添加到结构的末尾,使用我的库的人通常不会分配这个struct他/她自己,而是接收指向它的指针作为回调函数的参数。这就是我的图书馆所做的一切,用户永远不需要使用这个struct回调图书馆。
当旧程序与新版本的库一起运行时,可能的情况有两种:
- 在正常情况下(即旧程序收到指向此
struct的指针并读取它需要的字段),我的库将从现在开始发送指向更大struct的指针,但旧程序不会知道并且不在乎。 - 如果旧程序出于某些未知原因分配了这个
struct,它仍然会分配一个较小的结构(这确实是程序在编译时知道的),但我的库不知道它并不关心,因为它永远不需要从用户那里接收这个struct,它只将它作为一个指针发送。
在之前的讨论中,也有人发布了来自Linux Program Library HOWTO — §3.6. Incompatible Libraries的这句话:
当新版本的库与旧版本二进制不兼容时,soname 需要更改。在 C 语言中,库不再兼容二进制有四个基本原因:
函数的行为发生变化,使其不再符合其原始规范,
导出的数据项发生变化(例外:将可选项添加到结构的末尾是可以的,只要这些结构仅在库中分配)。
李>导出的函数被移除。
导出函数的接口发生变化。
案件编号。 2 似乎在谈论不透明的结构。我的struct 不是不透明的,但情况很相似。但真正的问题是,正如我所说,我还没有找到一个单一的场景会在此更改后破坏二进制兼容性。
所以问题还是一样:这是次要版本还是主要版本更改?
【问题讨论】:
-
您的选择。尽管/因为第 2 点,该更改需要更改主要版本。您似乎不愿意进行主要版本更改 - 但您没有解释为什么?这主要是任意的。我会选择专业,但你对未成年人的论点也支持 AFAICS。
-
@Johnathan 在之前的讨论中,我没有解释很多细节,通常向
struct添加字段确实需要更改主要版本。但是,幸运的是,在这种情况下并非如此。如果新版本的源代码和二进制文件都与以前的版本兼容,我认为是语义版本控制本身表明我应该只增加次要版本号而不是主要版本号。我的意思是,这不是语义版本控制的重点,阅读版本更改并准确理解它的含义吗? -
正如我所说,您的选择。该决定可能取决于非技术(非语义)问题——您的客户群将如何改变主要版本而不是次要版本;您的营销部门是否更愿意更改主要版本以允许对正在进行的开发等进行更令人兴奋的宣传等。您是否希望并且在技术上可以将共享对象版本与营销版本分离?此时,您需要做出决定。无论您选择哪种方式,您的客户都不太可能抱怨。
-
您是否提供了一个函数来释放分配的结构,或者分配的结构总是在一个单元中分配,以便简单地调用
free()就足够了。你应该提供这样的功能吗?这让您在未来有更大的灵活性。但是,它的存在与否不一定是控制因素。并且“旧”程序仍然可以分配结构的副本并使用它并释放它。如果额外字段需要辅助分配,则会出现重大问题——因此,我假设额外字段是简单的非指针字段。 -
因此,您希望别人给您的答案是“(仅)次要版本的更改是可以的”。用不超过两个音节的词来说,就是这样。这也是我的第一条评论,虽然没有那么明确。
标签: c struct shared-libraries versioning semantic-versioning