OVH Cloud OVH Cloud

miracle de la récursion

52 réponses
Avatar
Christophe
Bonjour

1 int queSuisJe( int* Tablo, const int TailleTablo )
2 {
3 if ( TailleTablo == 1 )
4 return Tablo[0];
5 else
6 return Tablo[TailleTablo - 1] + queSuisJe( Tablo, TailleTablo - 1 );
7 }

Je ne comprends pas comment le Tablo[0] de la ligne 4 peut stocker le
résultat ?
Quelqu'un pourrait il m'éclairer ?
Merci d'avance

Christophe

10 réponses

2 3 4 5 6
Avatar
Richard Delorme

Si tu
n'appelles la fonction qu'une seule fois, ce n'est pas la peine de la
générer en ligne.


Je ne suis pas tellement d'accord. Si une fonction n'est appelée qu'une
seule fois, cela signifie qu'elle n'est appelée que d'un seul endroit. Or,
générer en ligne une telle fonction n'augmente pas la taille du code
exécutable, au contraire puisque les coûts d'appel et de retour de la
fonction sont supprimés. Si plusieurs fonctions dans un même programme
satisfont ce critère, il est possible que le bénéfice sur la taille du code
et le temps d'exécution ne soit pas négligeable. AMHA, les fonctions qui ne
sont appelées que d'un seul point (ce qui inclut les fonctions appelées une
seule fois) devrait être systématiquement mises en ligne, et ce
indépendamment de leur taille d'ailleurs.

--
Richard

Avatar
kanze
Christophe de VIENNE wrote in message
news:<newscache$nmc3qh$u6d$...
wrote:
"Pierre Maurette" <mmaauurreettttttee.ppiieerrrree@@ffrreeee.ffrr> wrote
Le seul cas où l'appel est remplacé par une valeur immédiate, c'est
avec tous les commutateurs qui vont bien, et si douze est déclarée
inline.


Ça dépend du compilateur. Sans démander une certaine optimisation,
c'est probable qu'elle ne soit jamais générée en ligne. Avec les
meilleurs compilateurs, si le profiler dit que c'est là que ça
coince, le compilateur génèrera la fonction en ligne, même si
l'appel est virtuel, et même si la définition de la fonction se
trouve dans une autre module. (D'accord, d'aussi bons compilateurs
sont rares. Mais ils existent.)


Est-ce que tu as des exemples de tels compilateurs (juste histoire de
compléter ma culture en la matière) ?


Il y en a plusieurs : je sais que HP en a un (mais je ne sais pas si
c'est commercialisé ou non), on m'a dit que le compilateur de SGI en est
capable aussi. Et il y a prèsque 10 ans, le compilateur de Cray en était
capable.

La technologie est connu.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
kanze
Richard Delorme wrote in message
news:<3fe1a4e6$0$6968$...

Si tu n'appelles la fonction qu'une seule fois, ce n'est pas la
peine de la générer en ligne.


Je ne suis pas tellement d'accord. Si une fonction n'est appelée
qu'une seule fois, cela signifie qu'elle n'est appelée que d'un seul
endroit. Or, générer en ligne une telle fonction n'augmente pas la
taille du code exécutable, au contraire puisque les coûts d'appel et
de retour de la fonction sont supprimés. Si plusieurs fonctions dans
un même programme satisfont ce critère, il est possible que le
bénéfice sur la taille du code et le temps d'exécution ne soit pas
négligeable. AMHA, les fonctions qui ne sont appelées que d'un seul
point (ce qui inclut les fonctions appelées une seule fois) devrait
être systématiquement mises en ligne, et ce indépendamment de leur
taille d'ailleurs.


Trouver les fonctions en question exige un certain effort. Si la
fonction n'est pas dans un chemin critique, ça ne vaut pas la peine.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Alain Naigeon
"Gabriel Dos Reis" a écrit dans le message
news:

Première réaction partielle :

"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le
message

| news:
| > "Alain Naigeon" writes:
|
| Merci pour ta réponse, il me faut un peu de temps pour
| la digérer. Mais j'ai tout de même une question immédiate :
|
| void f()
| {
| if( false)
| { /*
| ...
| */
| }
|
|
| Est-ce que le langage autorise une optimisation à :
| void f() { }
| ?

As-tu vraiment voulu dire « commentaire » dans la branche de if ?
Si, oui, alors la sémantique dynamique est équivalente effectivement à
void f() { }. Si non, je ne comprends pas ta question. Veux-tu dire
que parce qu'il y a « false », le fragment suivant

void f() { if (false) { toto; } }

où le nom « toto » n'est jamais déclaré doit être considéré valide ?



J'ai vraiment du mal à comprendre ce raisonnement : dès lors
qu'il n'y aura jamais exécution, en quoi la validité est-elle
nécessaire ?? Qu'un compilateur vérifie ce qui peut être exécuté
éventuellement, bravo, c'est ce qu'on attend de lui ; mais de là
à vérifier ce qui, à coup sûr, n'aura jamais la main - et par con-
séquent, n'a pas à être alloué, initialisé, etc - alors là, c'est too
much pour moi ;-) Du moins, la *raison* m'échappe.

Est-ce que tu ne te sens pas capable de prouver que
si deux programmes diffèrent uniquement parce qu'un

if( false) { toto ; }

et l'autre

// toto

ils vont toujours donner le même résultat (à condition que
ce qu'ils en en commun par ailleurs soit valide) ?

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France

Avatar
Gabriel Dos Reis
"Alain Naigeon" writes:

| "Gabriel Dos Reis" a écrit dans le message
| news:
|
| Première réaction partielle :
|
| > "Alain Naigeon" writes:
| >
| > | "Gabriel Dos Reis" a écrit dans le
| message
| > | news:
| > | > "Alain Naigeon" writes:
| > |
| > | Merci pour ta réponse, il me faut un peu de temps pour
| > | la digérer. Mais j'ai tout de même une question immédiate :
| > |
| > | void f()
| > | {
| > | if( false)
| > | { /*
| > | ...
| > | */
| > | }
| > |
| > |
| > | Est-ce que le langage autorise une optimisation à :
| > | void f() { }
| > | ?
| >
| > As-tu vraiment voulu dire « commentaire » dans la branche de if ?
| > Si, oui, alors la sémantique dynamique est équivalente effectivement à
| > void f() { }. Si non, je ne comprends pas ta question. Veux-tu dire
| > que parce qu'il y a « false », le fragment suivant
| >
| > void f() { if (false) { toto; } }
| >
| > où le nom « toto » n'est jamais déclaré doit être considéré valide ?
|
|
| J'ai vraiment du mal à comprendre ce raisonnement

Ce n'était pas un raisonnement, c'était une question. :-/

| : dès lors
| qu'il n'y aura jamais exécution, en quoi la validité est-elle
| nécessaire ??

Parce que le fait qu'une instruction soit grammaticallement correcte
est indépendante de ce qu'elle soit effectivement exécutée.

-- Gaby
Avatar
Marc Boyer
Alain Naigeon wrote:
J'ai vraiment du mal à comprendre ce raisonnement : dès lors
qu'il n'y aura jamais exécution, en quoi la validité est-elle
nécessaire ??


Peut être parce que dans la majorité des compilateurs,
on vérifie la syntaxe avant d'évaluer la sémantique.

Qu'un compilateur vérifie ce qui peut être exécuté
éventuellement, bravo, c'est ce qu'on attend de lui ; mais de là
à vérifier ce qui, à coup sûr, n'aura jamais la main - et par con-
séquent, n'a pas à être alloué, initialisé, etc - alors là, c'est too
much pour moi ;-) Du moins, la *raison* m'échappe.


Ceci dit, c'est bien pratique. En C par exemple, quelqu'un
voulait faire une macro freeToto(X) qui ne liberait que des
pointeurs sur un objet de type Toto. On a proposé
#define freeToto(X) do {
if (0) {
Toto *t;
t=X;
*t=*X;
}
free(X);
} while (0);

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Jean-Marc Bourguet
writes:

Il y en a plusieurs : je sais que HP en a un (mais je ne sais pas si
c'est commercialisé ou non),


La doc a l'air de dire que -O4 pourrait fait (Performs level 4
optimization. This includes level 3 optimizations plus full
optimizations across the entire application program.) mais il n'y a
pas de description plus precise des optimisations faites et je ne vois
pas comment faire generer de l'assembleur par le linker pour verifier.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Loïc Joly
Gabriel Dos Reis wrote:

| Euh... c'est juste syntaxique, la récursivité ?

et surtout lexicale.

Plus généralement, est-ce que

extern bool some_test();

void f() { if (some_test()) f(); }

est un appel récursif ?

La réponse, comme celle donnée avant est oui.

| Je trouve l'exemple astucieux et intéressant, mais c'est

ça dépend, je trouve que l'exemple montre peu de familiarité avec la
récursivité et la théorie des langages ;-)


Tout à fait.

[...]


Considére un langage où un nom ne peut être utilisé que si un binding
(i.e. une association entre ce nom et l'entité qu'il désigne) a été
préalablement établi. Ce qui semble relever du bon sens : si j'utilise
un nom quelque part, je sais exactement ce qu'il désigne et je peux
donner la valeur de ce qu'il désigne.

Eh bin, dans un tel langage il n'est pas possible de définir une
fonction comme

let f x = if (true) true else f(x - 1);

La raison est toute simple : la validité d'une expression est
lexicale.

dans

if (true) true else f(x - 1);

on ne sait pas ce que désigne « f » -- puisqu'on ne lui a pas encore
établi de binding. Note bien qu'ici la seule présence (lexicale) de f fout
tout en l'air.

Pour arriver à faire de la recursivité, il faut un opérateur de point
fixe[1]. Par exemple, « rec » est l'opérateur de point fixe pour les
fonctions dans (O)Caml.

let rec f x = if (true) true else f(x - 1);


C'est dommage, dans les docs OCaml que je viens de lire, les seules
mentions que je vois à rec, c'est du style let f est non récursif, let
rec f l'est, sans plus de détail. :(

[1] un opérateur de point fixe Fix est un opérateur qui satisfait
l'équation

Fix(f) = f(Fix(f)) pour tout f.


Là, j'ai du mal à concrètiser. Peux-tu pour m'aider à me décrasser les
méninges donner un exemple d'opérateur de point fixe pour les fonctions
de R dans R ?

--
Loïc, qui ne regrette pas d'avoir posé sa question à la noix

Avatar
Alain Naigeon
"Gabriel Dos Reis" a écrit dans le message
news:
"Alain Naigeon" writes:
| : dès lors
| qu'il n'y aura jamais exécution, en quoi la validité est-elle
| nécessaire ??

Parce que le fait qu'une instruction soit grammaticallement correcte
est indépendante de ce qu'elle soit effectivement exécutée.


Ma question était : pourquoi exiges-tu la correction grammaticale
pour du code dont une instruction valide [ if( false) ] exclut qu'il
soit jamais exécuté ? Est-ce que la compilation est une esthétique,
ou une pratique ? Et cette fois c'est moi qui demande ça ;-)

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France

Avatar
Alain Naigeon
"Loïc Joly" a écrit dans le message news:
brvjas$c2j$

Gabriel Dos Reis wrote:
Pour arriver à faire de la recursivité, il faut un opérateur de point
fixe[1]. Par exemple, « rec » est l'opérateur de point fixe pour les
fonctions dans (O)Caml.

let rec f x = if (true) true else f(x - 1);


C'est dommage, dans les docs OCaml que je viens de lire, les seules
mentions que je vois à rec, c'est du style let f est non récursif, let
rec f l'est, sans plus de détail. :(

[1] un opérateur de point fixe Fix est un opérateur qui satisfait
l'équation

Fix(f) = f(Fix(f)) pour tout f.


Là, j'ai du mal à concrètiser. Peux-tu pour m'aider à me décrasser les
méninges donner un exemple d'opérateur de point fixe pour les fonctions
de R dans R ?


Moi, déjà, ce que je comprends pas, c'est "let f x =" [avec ou sans rec]
Ca s'écrit comment en C++ ?

--

Français *==> "Musique renaissance" <==* English
midi - facsimiles - ligatures - mensuration
http://anaigeon.free.fr | http://www.medieval.org/emfaq/anaigeon/
Alain Naigeon - - Strasbourg, France


2 3 4 5 6