5 astuces C++ pour les programmeurs C
Le C++ gagne du terrain dans de nombreuses applications embarquées, en particulier celles qui ne reposent pas sur de grandes quantités de code hérité.
Au cours des dernières années, C++ est devenu un langage plus populaire à utiliser dans les systèmes embarqués que C. Ne vous méprenez pas, C continuera d’être un langage dominant pour les années à venir, mais C++ offre aux développeurs des outils modernes à exploiter lorsque concevoir un code plus réutilisable, évolutif et portable. Les équipes ne se contentent pas d’abandonner le C, mais au contraire, lorsqu’elles démarrent le développement de nouveaux produits, elles adoptent plutôt le C++. Le langage a évolué avec le temps et offre de nombreuses améliorations par rapport au C. Dans cet article, examinons cinq astuces C++ simples que les programmeurs C apprécieront immédiatement.
Sommaire
Astuce #1 – Compilation conditionnelle à l’aide de Constexpr
Le fléau de nombreuses bases de code embarquées écrites en C est le grand nombre de directives de préprocesseur #if / #elif / #else. Les directives du préprocesseur sont souvent utilisées pour compiler conditionnellement du code dans et hors de l’image. Par exemple, si nous avons trois versions différentes de matériel, nous créons souvent une macro qui est utilisée puis vérifiée en fonction de la configuration de construction pour déterminer les affectations de broches, etc. Le problème avec les compilations conditionnelles utilisant le préprocesseur est que le code devient désordonné et parfois assez difficile à suivre.
À partir de C++ 17, le langage a introduit la possibilité pour les développeurs de compiler conditionnellement du code à l’aide de constexpr. Les développeurs peuvent tirer parti de cette fonctionnalité du compilateur pour optimiser le code basé sur des modèles et même pour supprimer les directives de préprocesseur qui utilisent des blocs #ifdef. Par exemple, si nous avions une base de code qui avait trois configurations matérielles différentes, nous pourrions trouver que notre code pour initialiser GPIO ressemble à ceci :
annuler Gpio_Init()
{
#ifdef __MATÉRIEL_REV1__
// Initialiser le jeu de broches #1
#elif __MATÉRIEL_REV2__
// Initialiser le jeu de broches #2
#elif __HARDWARE_REV_3__
// Initialiser le jeu de broches #3
#fin si
}
Le code ci-dessus est configurable, mais il est assez désagréable à regarder. Oui, un IDE moderne masquera certaines des options, mais ce n’est tout simplement pas une solution très élégante et conduit à un code désordonné. En C++, nous pouvons tirer parti de l’optimisation du temps de compilation constexpr et écrire du code comme celui-ci :
constexpr Hardware_t HardwareRev = Hardware::Rev1
annuler Gpio_Init()
{
si constexpr (HardwareRev == Hardware::Rev1)
{
// Initialiser le jeu de broches #1
}
sinon si constexpr (HardwareRev == Hardware::Rev2)
{
// Initialiser le jeu de broches #2
}
sinon si constexpr(HardwareRev == Hardware::Rev3)
{
// Initialiser le jeu de broches #3
}
}
Lorsque nous compilons le code ci-dessus pour Rev2, seul le code pour « Initialize pin set #2 » en fait notre exécutable. Si nous compilons pour Rev1, seul le code pour « Initialize pin set #1 » le transforme en exécutable, et ainsi de suite.
Astuce # 2 – À distance pour les boucles
Un mécanisme fondamental de contrôle de flux en C et C++ est la boucle for. La boucle C for a été bloquée à l’âge des ténèbres en n’ayant pas d’option simplifiée basée sur la plage. Par exemple, des langages comme Python permettent à un programmeur d’itérer sur une plage en utilisant une syntaxe telle que :
pour x dans la plage (1, 5)
impression(x)
En C, il faut écrire (en fonction du standard C utilisé bien sûr) :
for(int x = 1; x <= 5; x++)
{
printf(« %d rn », x);
}
À partir de C++ 11, une version supplémentaire de la boucle for a été ajoutée pour faciliter le travail avec des valeurs étendues. Par exemple, si l’on voulait écrire les exemples de code ci-dessus en C++, on pourrait maintenant l’écrire comme suit :
int MesNums[] = {1, 2, 3, 4, 5} ;
for(int i : MyNums)
{
std::cout << I << std::endl;
}
Au début, pour un développeur C, cela peut sembler gênant ; Cependant, étant donné la fréquence à laquelle nous voulons travailler sur une plage dans une énumération ou un objet, la syntaxe est plus propre et plus facile à lire.
Astuce #3 – Utilisez Auto
Pour les développeurs C, auto est un mot-clé de langage obsolète depuis longtemps. Les développeurs avaient l’habitude d’utiliser auto pour spécifier une variable limitée à la portée actuelle. Auto est un spécificateur de classe de stockage comme static, seulement il spécifie que le stockage est local et que la variable doit être automatiquement détruite une fois hors de portée, contrairement à static qui permet à la variable de persister.
En C++, auto peut être un mot-clé très utile qui indique au compilateur d’attribuer automatiquement le type de données au développeur. Par exemple, dans l’astuce #2, nous avions le code de boucle for suivant :
int MesNums[] = {1, 2, 3, 4, 5} ;
for(int i : MyNums)
{
std::cout << I << std::endl;
}
MyNums est déjà défini comme un int, donc je peux laisser le compilateur décider du type qui doit être utilisé pour i comme suit :
for(auto i : MyNums)
{
std::cout << I << std::endl;
}
Au début, cela peut sembler bâclé. En tant que développeur, ne devrais-je pas contrôler mes types de variables ? La réponse est oui, mais nous devrions autoriser le compilateur à gérer les types là où cela pourrait nous faire gagner du temps ou là où nous ne nous soucions pas de les spécifier manuellement. Est-ce que nous nous soucions si i est par exemple uint8_t, uint16_t, uint32_t et ainsi de suite ? Probablement pas. Nous voulons juste quelque chose qui peut itérer sur la plage de un à cinq et le compilateur est plus que capable de décider. Auto peut également aider lorsque nous modifions un type de données. Nous pouvons le changer en un seul endroit sans avoir à nous soucier de changer quoi que ce soit en aval qui l’utilise ou interagit avec lui.
Astuce #4 – L’opérateur du vaisseau spatial
Cela peut parfois être ennuyeux lorsque vous devez écrire une instruction conditionnelle qui vérifie si une valeur est inférieure, supérieure ou égale à une autre valeur. Tout récemment, C++20 a ajouté un opérateur de comparaison à trois voies qui peut simplifier la lisibilité et le code. Cet opérateur <=>, est souvent appelé l’opérateur « vaisseau spatial » car il ressemble à un vaisseau spatial.
L’utilisation de l’opérateur de vaisseau spatial est simple. Par exemple, si nous avons deux variables et que nous voulons une comparaison à trois facteurs, nous pouvons écrire un code comme celui-ci :
int Var1 = Valeur1 ;
int Var2 = Valeur2 ;
auto Résultat = Var1 <=> Var2 ;
Si Var1 < Var2, alors le résultat sera inférieur à 0. Si Var1 > Var2, le résultat sera supérieur à 0. Si Var 1 est égal à Var2, alors le résultat sera 0.
Astuce # 5 – Obtenir la taille d’une chaîne
Les chaînes en C ne sont rien de plus qu’un tableau de caractères avec ‘