我用 C 语言编写类型安全的泛型数据结构。

这是一篇关于在 C 语言中实现类型安全泛型数据结构的文章,主要内容总结如下:

  • 通用技术介绍:使用联合(union)将类型信息与泛型数据结构关联,通过这种方式可以实现各种数据结构的泛型化,本文以基本链表为例进行说明。

    • 具体代码示例(1):通过typedef定义结构体FooBar,并使用list_prepend函数向不同类型的链表中添加元素,展示了基本的泛型链表操作,但这种方式存在一些缺点,如难以找到类型和函数的定义位置、代码补全效果不佳、二进制大小和构建时间增加以及需要使用类型前缀函数等。
    • 具体代码示例(2):使用void *实现数据结构的泛型化,虽然不是类型安全的,但介绍了相关代码和注意事项,如使用malloc分配内存以及推荐使用Arenas替代malloc等。同时指出这种方式在内存和性能方面存在一些问题,如需要两次分配内存、数据指针使用不必要的内存以及遍历列表时可能会出现两次缓存未命中等。
    • 具体代码示例(3):使用内联存储(Inline storage)来解决void *方式的问题,通过使用灵活数组成员(Flexible Array Member)将数据存储在节点内部,减少了内存分配和缓存未命中的问题,但需要传递数据大小。还介绍了list_alloc_front函数用于直接初始化节点内存,并通过__typeof__()来处理类型转换。
    • 具体代码示例(4):使用联合和三元运算符来实现类型检查,确保向列表中添加的元素类型与列表的payload类型相同,避免类型错误。还介绍了在不同编译器上的处理方式,如在不支持__typeof__()的编译器上可以使用三元运算符代替。同时提到可以通过payload进行类型安全的返回,并将细节留给读者作为练习。
  • 参数传递问题:在 2025 年底之前发布的 C 编译器中,即使变量具有相同的类型定义,编译器也会认为它们是不同的定义,导致一些错误。通过typedef可以解决这个问题,使代码能够正常工作。
  • 结论:这种泛型数据结构的实现方式可以用于各种数据结构,甚至包括带有多个关联类型的哈希映射等。并提供了更多详细信息的代码链接。

文章还感谢了[Martin Fouilleul]的鼓励和反馈。同时提到了[stb_ds.h]作为类型安全泛型数据结构的示例,但指出其技术不如本文介绍的通用,并说明了一些注意事项和相关链接。

阅读 13
0 条评论