En fait, c'est pas du tout pour tester les templates.
C'est pour forcer l'évaluation à la compilation. et pouvoir utiliser static_assert sur des choses qui ne sont en pratique jamais des variables même si du point de vue de compilateur, ça n'est pas exclu.
Et là, oui j'ai un vrai besoin derrière : C'est du code pour microcontroleur. (pour **petit** microcontroleur).
J'ai donc besoin qu'un maximum de trucs soit vraiment évalués et verifiés compile-time pour 3 raisons.
D'abord, j'ai pas envie que ça passe du temps à faire ces évaluations au runtime, la plupart du temps, c'est pipeau comme raison, mais il peut y avoir des fois où c'est vraiment critique.
Deuxièmement j'ai pas envie d'encombrer la minuscule rom avec un algo qui peut être entièrement exécuté dans la phase de compilation. Dans mon cas, cet algo peut à lui seul bouffer 20% de la ROM et j'ai pas envie de l'évaluer moi même à la main. Il faut que le compilateur le fasse.
Troisièmement, j'ai envie de vérifier la cohérence des paramètres dans la phase de compilation car si c'est foireux, Il n'y aura de toute façon aucun moyen de debugger au runtime sur la machine cible.
donc
Il faut que ça soit évalué compile-time. (c'est un MUST, pas un MAY ou un SHOULD)
Il faut que ça couine compile-time si on donne des paramètres incohérents ou hors limites.
Il faut que ça couine si c'est pas évaluable à la compilation, car ça révèle un mauvais usage.
Evidemment je pourrais faire tout ça à grand coup de macros, ce qui est d'ailleurs la façon classique de faire.
mais dans des algos pas tout a fait triviaux, ça deviens rapidement illisible. comme dans l'exemple ci dessous
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #define UBRR_VALUE (((F_CPU) + 8UL * (BAUD)) / (16UL * (BAUD)) -1UL)
#if 100 * (F_CPU) > (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL))
#define USE_2X 1
#elif 100 * (F_CPU) < (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))
#define USE_2X 1
#else
#define USE_2X 0
#endif
#if USE_2X
/* U2X required, recalculate */
#undef UBRR_VALUE
#define UBRR_VALUE (((F_CPU) + 4UL * (BAUD)) / (8UL * (BAUD)) -1UL)
#if 100 * (F_CPU) > (8 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL))
#warning "Baud rate achieved is higher than allowed"
#endif
#if 100 * (F_CPU) < (8 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))
#warning "Baud rate achieved is lower than allowed"
#endif
#endif /* USE_U2X */ |
Pour moi, ce qui manque, c'est la possibilité écrire des fonction du genre
constexpr int foo(constexpr int param);//invalide
Autrement dit, des fonction qui ne peuvent être utilisé QUE avec des params qui sont déjà des constantes connues.
Partager