Declaración static_assert
Lleva a cabo una comprobación de aserción en tiempo de compilación.
Contenido |
[editar]Sintaxis
static_assert( bool-constexpr, cadena-no-evaluada) | (1) | ||||||||
static_assert( bool-constexpr) | (2) | (desde C++17) | |||||||
static_assert( bool-constexpr, expresión-constante) | (3) | (desde C++26) | |||||||
Declara una aserción estática. Si la aserción falla, el programa queda mal formado y puede generarse un mensaje de error de diagnóstico.
[editar]Explicación
bool-constexpr | - |
| ||||
cadena-no-evaluada | - | una literal de cadena no evaluada que aparecerá como el mensaje de error. | ||||
expresión-constante | - | una expresión constantemsg que satisface todas las condiciones siguientes:
|
Una declaración static_assert puede aparecer en el espacio de nombres y bloque ámbito (como una declaración de bloque) y dentro del cuerpo de una clase (como una declaración de miembro).
Si bool-constexpr está bien formada y se evalúa como true, o se evalúa en el contexto de una definición de plantilla y la plantilla no está instanciada, esta declaración no tiene efecto. De lo contrario, se emite un error de tiempo de compilación y el mensaje proporcionado por el usuario, si lo hay, se incluye en el mensaje de diagnóstico.
El texto del mensaje proporcionado por el usuario se determina de la siguiente manera:
- Si el mensaje coincide con los requisitos sintácticos de cadena-no-evaluada, el texto del mensaje es el texto de cadena-no-evaluada.
| (desde C++26) |
[editar]Nota
El estándar no requiere que un compilador imprima el texto literal de message, aunque los compiladores generalmente lo hacen en la medida de lo posible.
Dado que message tiene que ser un literal de cadena, no puede contener información dinámica o incluso una expresión constante que no sea un literal de cadena en sí mismo. En particular, no puede contener el nombre del argumento de plantilla de tipo. | (hasta C++26) |
Prueba de característica | Valor | Estándar | Comentario |
---|---|---|---|
__cpp_static_assert | 200410L | (C++11) | static_assert (sintaxis (1)) |
201411L | (C++17) | static_assert de un solo argumento (sintaxis (2)) | |
202306L | (C++26) | Mensajes de error generados por el usuario (sintaxis (3)) |
[editar]Palabras clave
[editar]Ejemplo
#include <format>#include <type_traits> static_assert(03301==1729);// desde C++17 la cadena de mensaje es opcional template<class T>void swap(T& a, T& b)noexcept{ static_assert(std::is_copy_constructible_v<T>, "El intercambio requiere copia"); static_assert(std::is_nothrow_copy_constructible_v<T>&&std::is_nothrow_copy_assignable_v<T>, "El intercambio requiere copia/asignación nothrow");auto c = b; b = a; a = c;} template<class T>struct data_structure { static_assert(std::is_default_constructible_v<T>, "La estructura de datos requiere elementos construibles por defecto");}; template<class>constexprbool dependent_false =false;// Solución alternativa antes de CWG2518/P2593R1 template<class T>struct bad_type { static_assert(dependent_false<T>, "Error en la instanciación, solución alternativa"); static_assert(false, "Error en la instanciación");// Está bien debido a CWG2518/P2593R1}; struct no_copy { no_copy(const no_copy&)= delete; no_copy()=default;}; struct no_default { no_default()= delete;}; #if __cpp_static_assert >= 202306L// Aún no es C++ real (std::format debe ser constexpr para funcionar): static_assert(sizeof(int)==4, std::format("Se esperaba 4, se obtuvo {}", sizeof(int)));#endif int main(){int a, b; swap(a, b); no_copy nc_a, nc_b; swap(nc_a, nc_b);// 1 [[maybe_unused]] data_structure<int> ds_ok;[[maybe_unused]] data_structure<no_default> ds_error;// 2}
Posible salida:
1: ERROR: la aserción estática falló: El intercambio requiere copia 2: ERROR: la aserción estática falló: La estructura de datos requiere elementos construibles por defecto 3: ERROR: la aserción estática falló: Se esperaba 4, se obtuvo 2
[editar]Informes de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
---|---|---|---|
CWG 2039 | C++11 | Se requería que solo la expresión antes de la conversión fuera constante. | La conversión también debe ser válida en una expresión constante. |
P2593R1 | C++11 | static_assert(false, ""); sin instanciar estaba mal formada. | Se hizo bien formada. |
[editar]Referenciass
- El estándar C++23 (ISO/IEC 14882:2023):
- 9.1 Preámbulo [dcl.pre](p: 10)
- El estándar C++20 (ISO/IEC 14882:2020):
- 9.1 Preámbulo [dcl.pre](p: 6)
- El estándar C++17 (ISO/IEC 14882:2017):
- 10 Declaraciones [dcl.dcl](p: 6)
- El estándar C++14 (ISO/IEC 14882:2014):
- 7 Declaraciones [dcl.dcl](p: 4)
- El estándar C++11 (ISO/IEC 14882:2011):
- 7 Declaraciones [dcl.dcl](p: 4)
[editar]Véase también
Muestra el mensaje de error dado y hace que el programa quede mal formado.. (directiva de preprocesador) | |
Aborta el programa si la condición especificada por el usuario no es verdadera (true). Puede ser desactivada para las versiones de lanzamiento. (macro de función) | |
(C++11) | Condicionalmente elimina una sobrecarga de función o especialización de plantilla de la resolución de sobrecargas. (plantilla de clase) |
Rasgos de tipo(C++11) | Define interfaces basadas en plantillas de tiempo de compilación para consultar las propiedades de los tipos |
Documentación de C para Static assertion |