119 votes

Qu'est-ce qu'une fonction trampoline ?

Lors de récentes discussions au travail, quelqu'un a fait référence à une fonction trampoline.

J'ai lu la description sur Wikipédia. Cela suffit pour se faire une idée générale de la fonctionnalité, mais j'aimerais quelque chose de plus concret.

Auriez-vous un petit extrait de code simple qui pourrait illustrer une trampoline?

2 votes

Dans le monde Microsoft, les trampolines sont généralement appelés "thunks". [Voici une page](http://books.google.com/books?id=aJ1av7UFBPwC&pg=PA280&lpg=PA280&dq=thunk+trampoline&source=web&ots=YQcG0nOf7Z&sig=PZA-Pbx19C9Mnw\_1myezK4x3QWQ&hl=en&sa=X&oi=book\_result&resnum=4&ct=result) tirée du livre "Modern C++ Design" d'Andrei Alexandrescu.

1 votes

0 votes

C'est essentiellement la forme généralisée de certaines fonctionnalités que vous pourriez implémenter avec setjmp/longjmp, à savoir éviter le dépassement de pile.

2voto

Michael Burr Points 181287

Dans le monde de Microsoft, les trampolines sont généralement appelés 'thunks'.

Voici une page de "Modern C++ Design" d'Andrei Alexandrescu


1voto

avandeursen Points 1597

Voir aussi ce article de blog expliquant l'utilisation des trampolines dans les Extensions Réactives .NET (y compris un exemple de code).

1voto

Florian Points 800

Maintenant que C# a Local Functions, le Bowling Game coding kata peut être élégamment résolu avec un trampoline :

using System.Collections.Generic;
using System.Linq;

class Game
{
    internal static int RollMany(params int[] rs) 
    {
        return Trampoline(1, 0, rs.ToList());

        int Trampoline(int frame, int rsf, IEnumerable rs) =>
              frame == 11             ? rsf
            : rs.Count() == 0         ? rsf
            : rs.First() == 10        ? Trampoline(frame + 1, rsf + rs.Take(3).Sum(), rs.Skip(1))
            : rs.Take(2).Sum() == 10  ? Trampoline(frame + 1, rsf + rs.Take(3).Sum(), rs.Skip(2))
            :                           Trampoline(frame + 1, rsf + rs.Take(2).Sum(), rs.Skip(2));
    }
}

La méthode Game.RollMany est appelée avec un nombre de lancers : généralement 20 lancers s'il n'y a pas de spare ou de strike.

La première ligne appelle immédiatement la fonction trampoline : return Trampoline(1, 0, rs.ToList());. Cette fonction locale traverse récursivement le tableau de lancers. La fonction locale (le trampoline) permet au parcours de commencer avec deux valeurs supplémentaires : commencer avec le frame 1 et le rsf (résultat jusqu'à présent) 0.

À l'intérieur de la fonction locale, il y a un opérateur ternaire qui gère cinq cas :

  • La partie se termine au frame 11 : retourne le résultat jusqu'à présent
  • La partie se termine s'il n'y a plus de lancers : retourne le résultat jusqu'à présent
  • Strike : calcule le score du frame et continue le parcours
  • Spare : calcule le score du frame et continue le parcours
  • Score normal : calcule le score du frame et continue le parcours

La poursuite du parcours se fait en appelant de nouveau le trampoline, mais maintenant avec des valeurs mises à jour.

Pour plus d'information, recherchez : "tail recursion accumulator". Gardez à l'esprit que le compilateur n'optimise pas la récursion terminale. Donc aussi élégante que cette solution puisse être, elle ne sera probablement pas la plus rapide.

0voto

MSN Points 30386

Pour C, un trampoline serait un pointeur de fonction:

size_t (*trampoline_example)(const char *, const char *);
trampoline_example= strcspn;
size_t result_1= trampoline_example("xyzbxz", "abc");

trampoline_example= strspn;
size_t result_2= trampoline_example("xyzbxz", "abc");

Modifier : Des trampolines plus ésotériques seraient générés de manière implicite par le compilateur. Un exemple d'utilisation serait une table de saut. (Bien qu'il existe clairement des trampolines plus compliqués au fur et à mesure que vous commencez à essayer de générer du code compliqué.)

-2voto

thenry Points 9
typedef void* (*etat_type)(void);
void* etat1();
void* etat2();
void* etat1() {
  return etat2;
}
void* etat2() {
  return etat1;
}
// ...
etat_type etat = etat1;
while (1) {
  etat = etat();
}
// ...

3 votes

Pouvez-vous ajouter des commentaires ou des explications sur pourquoi ceci est un trampoline?

0 votes

Il s'agit d'un pointeur de fonction qui rebondit d'une fonction à l'autre en fonction de ce que la fonction qu'il appelle retourne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X