【发布时间】:2017-03-03 05:29:19
【问题描述】:
最近研究我的 C 肌肉并浏览了我一直在使用的许多库,这无疑让我对什么是好的实践有了一个很好的了解。我没有看到的一件事是返回结构的函数:
something_t make_something() { ... }
据我所知,这是“正确”的做法:
something_t *make_something() { ... }
void destroy_something(something_t *object) { ... }
代码 sn-p 2 中的架构比 sn-p 1 更受欢迎。所以现在我问,为什么我会直接返回一个结构,就像在 sn-p 1 中一样?在这两个选项之间进行选择时,我应该考虑哪些差异?
此外,这个选项比较如何?
void make_something(something_t *object)
【问题讨论】:
-
我看到的重要区别是复制与不复制以及堆与堆栈。
-
不要同时标记 C 和 C++。两种语言的同一个问题的答案非常不同。选择一个。
-
我进行了一些编辑,试图避免这个问题被标记为基于意见。 “最佳实践”可能是一条非常模糊的界限,一种选择比另一种更好的想法可能是一种主观的想法。如果问题的编辑版本与您想知道的内容相去甚远,请告诉我。
-
如果结构太大而无法像正常返回值一样返回(例如,在寄存器中),绝大多数 ABI 要求编译器将第一种形式转换为第二种形式,有效地传递一个
make_something函数将填充的隐藏指针。因此,从目标代码的角度来看,这两种形式基本上是相同的,唯一的区别是您希望您的 API 在客户端看起来像什么。出于这个原因,绝大多数时候我会选择表格#1,因为它要简单得多。让编译器完成传递指针的脏活。 -
@CodyGray:除了... ABI 兼容性可以通过使用不透明类型(Lundin 的回答)来实现,这需要通过指针传递。当它重要时,它真的很重要。