C 语义版本控制:次要还是主要变化?

C 语义版本控制:次要还是主要变化?,c,struct,semantic-versioning,C,Struct,Semantic Versioning,在一般规则中,只有在引入向后兼容功能时才增加次要数量,否则必须增加主要数量。libtool使用,但使用不同的算法 我有一个问题,关于什么是向后兼容的更改,什么不是 假设我编写了一个库,这个库的公共头包含一个名为foo的数据类型的typedef。在1.0.0版中,此typedef如下所示: typedef结构foo\t{ int x; int-y; }傅; 然后我决定更改数据类型,在下一个版本中,它将如下所示: typedef结构foo\t{ int x; int-y; intz; }傅; 我

在一般规则中,只有在引入向后兼容功能时才增加次要数量,否则必须增加主要数量。libtool使用,但使用不同的算法

我有一个问题,关于什么是向后兼容的更改,什么不是

假设我编写了一个库,这个库的公共头包含一个名为
foo
的数据类型的
typedef
。在1.0.0版中,此
typedef
如下所示:

typedef结构foo\t{
int x;
int-y;
}傅;
然后我决定更改数据类型,在下一个版本中,它将如下所示:

typedef结构foo\t{
int x;
int-y;
intz;
}傅;
我只在结构
foo\u t
中添加了一个字段。这似乎是一个向后兼容的变化,但是上面的结构实际上是另一个结构。我所做的并不是引入一个新函数,其余的都保持不变,而是改变了一些已经存在的东西

上面的数据类型通常用于与库函数交换数据,但是用户可能已将其用于其他目的。如果用户使用版本1.0.0编写了程序,并且最后一次更改构成向后兼容的更改,则用户的程序也必须使用此新版本进行编译

这个新版本将如何命名,1.1.0还是2.0.0

编辑


您可以阅读本讨论的进一步发展。

这将是一次重大的版本更改。结构布局被烘焙到最终用户程序中。添加或删除成员是一个突破性的改变;无论哪种方式,布局都发生了变化

引自-§3.6。不兼容的库:

当库的新版本与旧版本二进制不兼容时,soname需要更改。在C语言中,库不再与二进制兼容有四个基本原因:

  • 函数的行为会发生变化,从而不再满足其原始规范

  • 导出的数据项会发生更改(例外:只要这些结构仅在库中分配,向结构的末尾添加可选项是可以的)

  • 已删除导出的函数

  • 导出函数的接口将更改

  • 您会说,“上面的数据类型通常用于与库的函数交换数据,但是用户可能会将其用于其他目的。”如果该结构仅在内部使用,而未在公共API中公开,则可以。但听起来用户可以自己分配一个结构变量,这意味着这是一个突破性的改变


    您可以通过使用来保护您的库免受这种类型的搅动。隐藏结构的内容,让用户只传递指针。这正是
    文件*
    的工作原理:C标准没有定义
    文件
    的布局,作为最终用户,我们不知道其中的内容。

    感谢您给出了非常好的答案。我不能向用户隐藏我的
    struct
    ,因此不透明结构不是一个选项。大版本的变化,那就这样吧!请注意,通过使大小为动态(因此用户需要查询库以获取要分配的大小),或者通过在对象本身中包含大小甚至动态版本id,可以避免需要进行重大版本更改。对于后者,库将需要检查该大小/版本,以了解它正在处理的对象的版本(更多工作),但如果您希望在将来更改结构,则可能值得这样做。