Static assert — est un mécanisme du compilateur pour générer des erreurs à l'étape de compilation si une expression (condition) n'est pas vérifiée. Cette fonctionnalité a été ajoutée à partir de C++11 pour faciliter la programmation par modèles et améliorer la qualité du code.
Historique de la question.
Avant l'apparition de static_assert, les programmeurs utilisaient des astuces comme une structure avec une taille de tableau négative (par exemple char arr[condition?1:-1];), ce qui était moins lisible et moins pratique pour le diagnostic des erreurs. Ainsi, la nécessité d'une déclaration explicite des erreurs de compilation avec un message significatif est née.
Problème.
Dans la programmation par modèles, il est souvent nécessaire de diagnostiquer tôt (par exemple, interdire la création d'un objet avec un type ou un paramètre inapproprié). Sans vérification statique, ces erreurs n'apparaissaient qu'à l'étape de compilation du code final (parfois sous la forme d'une erreur inattendue et mal expliquée).
Solution.
Le mot-clé static_assert prend une expression booléenne et une chaîne de message. Si l'expression est fausse, la compilation échouera avec l'affichage du message.
Exemple de code :
static_assert(sizeof(int) >= 4, "int doit faire au moins 4 octets"); template<typename T> void foo(const T& obj) { static_assert(std::is_copy_constructible<T>::value, "T doit être copiable"); }
Caractéristiques clés :
Peut-on utiliser static_assert sans le deuxième argument ?
Oui, à partir de C++17, le deuxième argument est facultatif :
static_assert(sizeof(double) == 8); // le message sera par défaut
Les expressions static_assert s'exécutent-elles si la condition dépend des paramètres de modèle, mais le modèle n'est pas instancié ?
Non, static_assert ne se déclenche que lorsqu'il atteint le point d'instanciation, ce qui permet d'appliquer des vérifications uniquement pour les modèles utilisés.
Peut-on utiliser des expressions d'exécution (run-time) à l'intérieur de static_assert ?
Non, l'expression doit être calculable à l'étape de compilation (constexpr). Si l'expression n'est pas constexpr — il y aura une erreur de compilation.
Dans le code, static_assert a été utilisé avec une expression calculable uniquement en temps d'exécution (par exemple, la taille d'un fichier lors de la lecture d'entrée), ce qui a provoqué une erreur de compilation incompréhensible dans tout le système.
Avantages :
Inconvénients :
Il est nécessaire de garantir que le modèle Matrix ne peut être instancié qu'avec des types de données simples (POD), excluant des structures complexes.
template<typename T> class Matrix { static_assert(std::is_pod<T>::value, "Matrix ne peut être instancié que pour des types POD"); // ... };
Avantages :
Inconvénients :