# The Power of Ten
<br>
***"The power of ten"*** est un document publié par... la **NASA ???**
> *"Alors qu'est ce qu'il fait là ?"*
Eh bien, lors des missions de l'époque qui utilisait *le C comme langage informatique* pour coder par exemple ***le putain de robot qui est sur Mars*** (les gens l'oublient trop souvent) ou encore pour calculer les résultats exactes et prévoir parfaitement tout à l'avance dans ***une mission cruciale***, ces derniers étaient bien obligés d'avoir le code ***le plus sûr possible***, sans aucun ***leak***, sans aucun ***crash***. Bref un code ***space-proof***.
Alors pour cela, ils ont mit en place 10 règles implacables pour rédiger un code pareil. Alors certes, elles ne laissent presque aucune liberté et sont très restraignantes, mais en tout cas grâce à elles NASA est ce qu'elle est aujourd'hui.
> *PS : Ces règles ne sont pas forcément rudimentaires pour nos programmes à EPITECH, mais les duo stumpers sont ce qui se rapproche le plus d'une demande pareille alors c'est quand même important de savoir comment ça marche et comment bien l'utiliser*
Les 10 règles seront énoncées et expliquées des plus importantes et intéressantes à mettre en pratique pour vous et à savoir. Jusqu'à celles que, même moi, j'ai pas compris :skull:
---
<br>
1. ***Ne pas utiliser la heap***
Je vous renvoie sur le cours que j'ai fais sur la heap pour comprendre le choix des experts de la NASA.
Evidemment, c'est une règle qui est VRAIMENT très strictes, une fois que vous saurez bien gérer vos allocations dynamiques vous comprendrez à quel point c'est obstruant. Mais c'est une super alternative pour ***les stumpers** qui vous enleveront des points si il y a des leaks*.
---
<br>
2. ***Fonction à 1 seul usage***
Ce n'est pas vraiment une règle propre à NASA, en fin de compte c'est une règle ***généralisée*** que tous les bons développeurs utilisent.
> *Une fonction efficace, c'est une fonction qui sert à une seule chose. C'est une fonction précise, efficace et conscise*
C'est d'ailleurs un aspect qu'on essaie de vous enseigner à EPITECH en forçant les fonctions à faire *20 lignes au max pour garantir leur efficicaté*. Certes à certains moments c'est assez contraignant, mais au fil du temps, vous verrez que c'est ***la meilleure chose à faire***. Parce qu'une fonction de 80 lignes c'est facilement ***contre-intuitif***.
> *PS : ils avaient droit à 60 lignes eux D:<*
Prenons un exemple :
```c
static int check_message(char *message)
{
if (error dans le message)
return 84;
...;
return 0;
}
static int connect_to_db(int id, char *message)
{
if (error dans la connection de la db)
return 84;
...;
return 0;
}
static int send_message_to_id(char *message, int id)
{
if (error dans l_envoi du message)
return 84;
...;
return 0;
}
int treat_message(char *message, int id)
{
if (check_message(message) == 84) {
print_error(2, "Wrong type of message provided");
return 84;
}
if (connect_to_db(id, message) == 84) {
print_error(2, "Couldn't connect to db");
return check_db();
}
if (send_message_to_id(message, id) == 84) {
print_error(2, "Couldn't send the message to %d", id);
returb 84;
}
return 0;
}
```
Et voilà, votre *"tronc d'arbre"* *treat_message ne check pas le message, ni ne se connecte a la db, ni n'envoie le message* mais on a séparé ces mendatories pour rendre le code compréhensif.
Si on avait tout fait dans treat_message, le contrôle de votre code et la compréhension de ce dernier serait ***largement réduits***.
---
<br>
3. ***Simple Control Flow***
ou "contrôle du flow simple de votre programme" est un aspect très important.
C'est une règle qui prévient l'utilisation de ***goto*** qui (vraiment) sert pas à grand chose, il y a un cours sur ce truc un peu claqué, l'utilisation de ***setjmp*** et ***longjmp*** qui sont des contrôles de très bas niveau qui sont utilisés en général par les experts du C et dont vous n'aurez pas besoin et bizarrement, l'utilisation de la ***récursion***, qui lorsque c'est mal géré peut *boucle inf super facilement*.
Petite règle, certes, mais pas des moindres.
> *PS : Après les frères si vous utilisez ces principes, personne ne va vous taper sur les doigts hein. C'est juste que bien utiliser la récursion c'est très fort mais c'est aussi très dur car c'est pas la même gestion d'erreur et de **flow** que dans une fonction itérative normale. Habituez vous juste à l'utiliser et ce sera très bien comme ça*
---
<br>
4. ***Compiler avec les bons arguments***
Ca parait bizarre dit comme ça mais le compilateur gcc sans argument manque de précision. C'est pourquoi pour ajouter les arguments -W... sont hyper importants pour catch toutes les erreurs possibles. Cela ne s'applique pas que pour la NASA en fait de compte *un code (qui marche) sans erreur lors de la compilation c'est un bon code*. Si vous avez encore pleins de warnings dans votre lib, ***pitié corrigez les...***
-Wall pour "all warnings" est le plus important car comme son nom l'indique il vous montrera tous les warnings que vous avez dans votre code.
-Werror cherchera toutes les autres erreurs qui sont peut-être passées à travers le -Wall
***-Wpandetic*** qui est celui important utilisé par la NASA est encore plus important pour catch les warnings car, si vous avez un warning, peu importe lequel, ***gcc ne compilera pas***. Alors c'est un peu tirer par les cheveux mais c'est efficace pour prevent tous les types d'erreurs possibles.
---
<br>
5. ***Eviter d'utiliser les pointeurs***
Alors ouais...
Comme dit, c'est la vie d'humain qui sont en jeu alors jouer avec les pointeurs c'est pas la meilleure des initiatives.
Vous avez vraiment pas besoin de suivre cette règle je vous jure. C'est surtout pour éviter une mauvaise utilisation de ces derniers qui fait fun fact très facile à ne pas comprendre.
Dans la même instance :
6. ***NE PAS utiliser les pointeurs sur fonction***
En fait là c'est surtout parce que c'est une addition au C qui est franchement évitable et qui rend la gestion d'erreur plus hardu que la normale.
---
<br>
7. ***Limiter les boucles***
Les experts de la NASA avaient ***P E U R*** des boucles inf, si bien qu'ils rajoutaient une limite *supplémentaire* à leurs conditions d'arrêt.
> *"Vous avez fait un millier d'unit tests qui prouvent que tout fonctionne parfaitement c'est bon il est prêt votre code là n'abusez pas...*
> *- We do not care, on va mettre une safety de plus"*
Un exemple vous fera tout de suite comprendre de quoi je parle :
```c
ll_t *find_val(ll_t *linked_list, int data)
{
while(linked_list != NULL) {
if (linked_list->val == data)
return linked_list;
if (PROBLEM) {
free(li);
return NULL;
}
li = li->next;
}
free(li):
return NULL;
}
// deviendra :
ll_t *find_val(ll_t *linked_list, int data)
{
int i = 0;
while(linked_list != NULL && i++ < MAX_VAL) {
if (linked_list->val == data)
return linked_list;
if (PROBLEM) {
free(li);
return NULL;
}
li = li->next;
}
free(li):
return NULL;
}
```
Techniquement si vous connaissez votre code, vous savez que ça ne sert *STRICTEMENT à rien*. Mais juste une prévention au cas où un ***SEUL minuscule problème*** arrive à la liste chaînée. Genre 1 erreur sur ***des centaines de millions de cas*** qui est un cas impératif dans l'éventuel possibilité que cette erreur arrive.
---
<br>
8. ***Vérifier TOUTES les variables de retour***
Alors ouais, celle là elle est quand même vachement drôle et complétement débile dite comme ça, mais je vous jure que dans un cas aussi précis qu'est *celui d'envoyer des hommes dans **l'espace***. Chaques variables comptent même la plus mondaine qu'est le retour de printf. Pour remédier à un éventuel problème, on peut manuellement ***manipuler la variable de retour d'une fonction***. Si bien qu'on peut faire en sorte qu'elle ne return en fait, ***rien*** !
```c
printf("Bonsoir"); // return 0 si ça marche
(void)printf("Bonsoir"); // ne return rien donc jamais de soucis
```
C'est un poil *overkill*, je vous l'accorde, mais cette technique leurs permet encore une fois, de tout contrôler. Si bien que toutes les fonctions dont ils n'ont pas besoin de connaître la variable de retour comme printf ***subiront ce procédé***.
---
<br>
9. ***Data hiding***
Ce principe vous décourage d'utiliser des variables globales, car si vous l'utilisez dans tout votre programme, il est difficile de savoir où est le problème car à ce moment, valgrind n'existait pas donc impossible de savoir où ça buguait à part en mettant des
```c
printf("hello");
```
partout jusque l'endroit où ça va crash. *(heureusement que valgrind est là)*
---
<br>
10. ***Limiter le preprocessor***
Wallah j'ai rien compris à ce chapitre je vous jure. Mais je crois c'est un truc avec les
```c
#ifdef ...
...
#end
```