| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente |
| lang:c:fonctions [2020/06/21 09:57] – Ajout source pour la taille par défaut de la pile root | lang:c:fonctions [2025/11/04 10:23] (Version actuelle) – Ajout de Prototype root |
|---|
| | ====Prototype==== |
| | |
| | <code cpp> |
| | [[deprecated("")]] template DLL_EXPORT void foo() const; |
| | </code> |
| | |
| ====Récursion==== | ====Récursion==== |
| |
| La récursion est gourmande en pile. Sachant que la taille est défaut est de 1 Mo, il est facile d'atteindre la saturation. [[https://docs.microsoft.com/en-us/windows/win32/procthread/thread-stack-size|Thread Stack Size]] {{ :lang:c:fonctions:thread_stack_size_-_win32_apps_microsoft_docs_2020-06-21_09_53_20_.html |Archive du 31/05/2018 le 21/06/2020}} | La récursion est gourmande en pile. Sachant que la taille est défaut est de 1 Mo sous Windows et 8 Mo sous Linux, il est facile d'atteindre la saturation. [[https://docs.microsoft.com/en-us/windows/win32/procthread/thread-stack-size|Thread Stack Size]] {{ :lang:c:fonctions:thread_stack_size_-_win32_apps_microsoft_docs_2020-06-21_09_53_20_.html |Archive du 31/05/2018 le 21/06/2020}} |
| |
| ===Tail Call Optimization=== | ===Tail Call Optimization=== |
| |
| Tous les algorithmes peuvent s'écrire soit sous forme de boucle (nécessite des données mutables), soit sous forme de récursion (l'immuabilité des données est à la discrétion de l'implémentation). | Tous les algorithmes peuvent s'écrire soit sous forme d'une boucle (nécessite des données mutables), soit sous forme d'une récursion (immuabilité des données possible). |
| |
| L'objectif du TCO est de convertir automatiquement une récursion (qui augmente la taille de la pile) en un ''jmp'' (qui n'incrémente pas la taille de la pile). | L'objectif du TCO est de convertir automatiquement une récursion (qui augmente la taille de la pile) en un ''jmp'' (qui n'incrémente pas la taille de la pile). |
| |
| Le TCO est actif lorsque le ''return'' fait appel à lui-même. | Cette optimisation ne se fait qu'en release : |
| | - clang utilise ''call'' en ''-O0'' et ''jne'' pour ''-O1'', ''-O2'', ''-O3'', ''-Os'', ''-Oz'', ''-Og'', ''-O'', ''-O4'', |
| | - gcc utilise ''call'' en ''-O0'', ''-O1'', ''-Og'' et ''jne'' pour ''-O2'', ''-03'', ''-Os'', ''-Oz'', |
| | - msvc utilise ''call'' en ''/O1'', ''/Ob'', ''/Od'', ''/Oi'', ''/Os'', ''/Ot'', ''/Oy'' et ''jmp'' en ''/O2'', ''/Ox''. |
| |
| * Exemple compatible avec ''TCO'' | * Exemple compatible avec ''TCO'' |
| </code> | </code> |
| |
| Mais attention, il faut que le ''return'' fasse uniquement appel à la fonction de récursion et rien d'autre après. | Mais attention, il faut que le ''return'' fasse uniquement appel à la fonction de récursion. |
| |
| [[https://medium.com/software-design/tail-call-optimization-in-c-829b4b257c9a|Tail Call Optimization in C++]] {{ :lang:c:fonctions:tail_call_optimization_in_c_-_software_design_-_medium_2020-06-16_4_28_30_pm_.html |Archive du 23/12/2018 le 16/06/2020}} | [[https://medium.com/software-design/tail-call-optimization-in-c-829b4b257c9a|Tail Call Optimization in C++]] {{ :lang:c:fonctions:tail_call_optimization_in_c_-_software_design_-_medium_2020-06-16_4_28_30_pm_.html |Archive du 23/12/2018 le 16/06/2020}} |
| * Exemple non compatible avec LTO. | * Exemple non compatible avec LTO. |
| |
| L'implémentation ci-dessous ne pourrait ne pas optimisée par le LTO. GCC 10, clang 10 optimise à partir de ''-O2'' mais Visual Studio 2019 n'optimise pas à ''/O2''. | L'implémentation ci-dessous pourrait ne pas être optimisée par le LTO. GCC 10, clang 10 optimise à partir de ''-O2'' mais Visual Studio 2019 n'optimise pas à ''/O2''. |
| |
| <code c> | <code c> |