Introduction des types de données algébriques pour C99
(github.com/Hirrolot)Datatype99
Une bibliothèque qui fournit des types de données algébriques sûrs et intuitifs, avec prise en charge du pattern matching exhaustif et de la résilience à la compilation. Elle est implémentée en pur C99, sans nécessiter d’outils externes.
Principales caractéristiques
- Sûreté des types : les variations de type inappropriées, le pattern matching incomplet et les accès à des champs invalides sont détectés à la compilation.
- Portabilité : un simple compilateur C99 conforme au standard suffit. Aucune bibliothèque standard, fonctionnalité spécifique à un compilateur ou à une plateforme, ni VLA n’est nécessaire.
- Prévisibilité : une sémantique formelle de génération de code est définie, ce qui garantit que le layout de données généré reste toujours identique.
- Erreurs faciles à comprendre : robuste face au code incorrect.
- Éprouvé en production : utilisé dans OpenIPC pour développer des logiciels de streaming temps réel pour caméras IP. Cela inclut une implémentation de RTSP 1.0 et environ 50 000 lignes de code propriétaire.
Installation
- Datatype99 se compose d’un fichier d’en-tête unique
datatype99.het d’une dépendance, Metalang99. - Si vous utilisez CMake, il est recommandé de le récupérer via
FetchContent. - Si nécessaire, il est possible d’utiliser des en-têtes précompilés afin de réduire le temps de compilation.
Utilisation
- Datatype99 n’est qu’un simple sucre syntaxique pour les unions taguées. C’est plus sûr et plus concis.
- Exemple d’arbre binaire :
- En C pur, il faut implémenter cela avec des structures, des unions et des énumérations.
- Avec Datatype99, une simple invocation de la macro
datatypesuffit pour la définition. - Le pattern matching permet aussi de calculer facilement la somme de l’arbre.
- Sûreté à la compilation : si l’on accède à une liaison d’une variante incorrecte, une erreur de compilation se produit.
- Flexibilité : les liaisons sont de type pointeur, donc elles peuvent être modifiées, puis déréférencées pour obtenir la valeur.
- Les fonctions constructrices de variantes sont générées automatiquement.
- Brève explication du pattern matching :
- Le cas par défaut se fait avec
otherwise. - Pour ignorer une liaison, on utilise
_. - Dans
ofetifLet, l’utilisation debreak/continueau niveau supérieur est interdite. Utiliser des labelsgoto.
- Le cas par défaut se fait avec
Syntaxe et sémantique
- Une définition de la grammaire EBNF et une explication de la sémantique sont fournies.
- Dans le fichier d’en-tête de la bibliothèque, il est recommandé d’utiliser les versions postfixées des macros.
Type unité
- Fourni via
UnitT99etunit_v99.
L’avis de GN⁺
- Datatype99 semble offrir un gros avantage en permettant d’utiliser des types de données algébriques en C de manière sûre et simple. Il paraît aussi facile à intégrer dans une base de code C existante.
- En revanche, en C++, certaines parties semblent faire doublon avec des fonctionnalités natives du langage comme les templates ou
constexpr. L’intérêt peut donc être moindre qu’en C. - La garantie de sûreté à la compilation est un atout majeur, mais cela semble plus difficile à exploiter dans les cas où le type de données change dynamiquement. C’est une limite du typage statique.
- Pour un petit projet, une implémentation manuelle peut suffire, mais à mesure que la base de code grandit, une bibliothèque comme Datatype99 semble pouvoir aider en termes de productivité et de fiabilité.
- Parmi les bibliothèques offrant des fonctionnalités similaires, on peut citer LibADT, Kitsune et P99.
Aucun commentaire pour le moment.