Static assert es un mecanismo del compilador para generar errores en tiempo de compilación si una expresión (condición) no se cumple. La funcionalidad se agregó a partir de C++11 para facilitar la programación de plantillas y mejorar la calidad del código.
Historia del asunto.
Antes de la aparición de static_assert, los programadores utilizaban trucos como estructuras con tamaño de matriz negativo (por ejemplo, char arr[condition?1:-1];), lo cual era menos legible y menos conveniente para diagnosticar errores. Así surgió la necesidad de declarar explícitamente los errores de tiempo de compilación con un mensaje significativo.
Problema.
En la programación de plantillas, a menudo surge la necesidad de diagnóstico temprano (por ejemplo, prohibir la creación de un objeto con un tipo o parámetro inapropiado). Sin una verificación estática, estos errores solo aparecían en la etapa de compilación del código final (a veces como un error inesperado y mal explicado).
Solución.
La palabra clave static_assert toma una expresión booleana y una cadena de mensaje. Si la expresión es falsa, la compilación terminará con un error que muestra el mensaje.
Ejemplo de código:
static_assert(sizeof(int) >= 4, "int debe ser al menos de 4 bytes"); template<typename T> void foo(const T& obj) { static_assert(std::is_copy_constructible<T>::value, "T debe ser constructible por copia"); }
Características clave:
¿Se puede usar static_assert sin el segundo argumento?
Sí, a partir de C++17 el segundo argumento es opcional:
static_assert(sizeof(double) == 8); // el mensaje será por defecto
¿Se ejecutan las expresiones de static_assert si la condición depende de parámetros de plantilla, pero la plantilla no se instancia?
No, static_assert se activa solo si llega al punto de instancia, lo que permite aplicar verificaciones solo para plantillas utilizadas.
¿Se pueden usar expresiones de tiempo de ejecución dentro de static_assert?
No, la expresión debe ser evaluable en tiempo de compilación (constexpr). Si la expresión no es constexpr, resulta en un error de compilación.
En el código se utilizó static_assert con una expresión evaluable solo en tiempo de ejecución (por ejemplo, el tamaño del archivo al leer la entrada), lo que provocó un error de compilación confuso en todo el sistema.
Ventajas:
Desventajas:
Se requiere garantizar que la plantilla Matrix solo se pueda instanciar con tipos de Plain Old Data (POD), excluyendo estructuras complejas.
template<typename T> class Matrix { static_assert(std::is_pod<T>::value, "Matrix solo se puede instanciar para tipos POD"); // ... };
Ventajas:
Desventajas: