C'est presque toujours à propos de ABI de stabilité. Binaire de la stabilité entre les versions de la bibliothèque. Dans le cas où il ne l'est pas, c'est parfois avoir dynamiquement la taille des structures. Rarement, il est très grand struct
s ou de performance.
Il est extrêmement rare que l'attribution d'un struct
sur le tas et de retour, il est presque aussi rapide que nous le retourner par valeur. L' struct
devrait être énorme.
Vraiment, la vitesse n'est pas la raison derrière la technique 2, le retour-en-aiguille, au lieu de revenir par valeur.
Technique 2 existe pour ABI stabilité. Si vous avez un struct
et de la prochaine version de la bibliothèque ajoute un autre 20 champs, les consommateurs de votre précédente version de la bibliothèque sont binaires compatibles s'ils sont remis pré-construit des pointeurs. Les données supplémentaires au-delà de la fin de l' struct
qu'ils savent à propos de quelque chose qu'ils n'ont pas à connaître.
Si vous retournez sur la pile, l'appelant est de l'allocation de la mémoire pour elle, et ils doivent être d'accord avec vous sur la façon dont il est grand. Si votre bibliothèque mis à jour depuis leur dernière reconstruit, vous allez à la corbeille de la pile.
Technique 2 vous permet également de masquer les données supplémentaires, à la fois avant et après le pointeur de votre retour (les versions ajouter des données à la fin de la struct est une variante de). Vous pourriez fin de l'ouvrage, avec un tableau de taille variable, ou ajouter le pointeur avec quelques données supplémentaires, ou les deux.
Si vous voulez pile-alloués struct
s dans un ABI stable, presque toutes les fonctions que parler à l' struct
d'avoir à passer des informations de version.
Donc
something_t make_something(unsigned library_version) { ... }
où library_version
est utilisé par la bibliothèque afin de déterminer quelle est la version de something_t
il est prévu de revenir et il change la façon dont beaucoup de la pile, il manipule. Ce n'est pas possible en utilisant la norme C, mais
void make_something(something_t* here) { ... }
est. Dans ce cas, something_t
pourrait avoir un version
champ de son premier élément (ou d'une taille de champ), et vous auriez besoin d'être renseigné avant de faire appel à make_something
.
D'autres bibliothèques de code en prenant un something_t
serait alors interroger l' version
champ pour déterminer quelle version de something_t
qu'ils travaillent avec.