Constant expressions
Varias variedades de expresiones se conocen como constant expressions .
Contenidos |
Expresión constante del preprocesador
La expresión que sigue a
#if
o
#elif
debe expandirse a
- operadores distintos de asignación , incremento, decremento , llamada a función , o coma cuyos argumentos son expresiones constantes del preprocesador
- constantes enteras
- constantes de carácter
-
el operador especial del preprocesador
defined.
Las constantes de caracteres, cuando se evalúan en
#if
-expressions, pueden interpretarse en el juego de caracteres fuente,
el juego de caracteres de ejecución, o algún otro juego de caracteres definido por la implementación.
|
La aritmética entera en expresiones
|
(desde C99) |
Expresión constante entera
Una expresión constante entera es una expresión que consiste únicamente de
- operadores distintos de asignación , incremento, decremento , llamada a función , o coma , excepto que los operadores de conversión solo pueden convertir tipos aritméticos a tipos enteros a menos que formen parte de un operando de sizeof , _Alignof (desde C11) (hasta C23) , alignas (desde C23) o typeof/typeof_unqual (desde C23) .
- constantes enteras
- constantes de enumeración
- constantes de carácter
- constantes flotantes , pero solo si se usan inmediatamente como operandos de conversiones a tipo entero
-
sizeofoperadores cuyos operandos no son VLA (desde C99)
|
(desde C11) |
|
(desde C23) |
Las expresiones constantes enteras se evalúan en tiempo de compilación. Los siguientes contextos requieren expresiones que se conocen como expresiones constantes enteras :
- El tamaño de un bit-field .
- El valor de una enumeration constant
-
La etiqueta
casede una switch statement - El tamaño de un array non-VLA (since C99)
- Conversión implícita conversion de entero a puntero.
|
(desde C99) |
|
(desde C11) |
|
(desde C23) |
Inicializador estático
Las expresiones que se utilizan en los inicializadores de objetos con duración de almacenamiento static y thread_local o declarados con el especificador de clase de almacenamiento constexpr (desde C23) deben ser literales de cadena o expresiones que pueden ser una de las siguientes
-
- operadores distintos de asignación , incremento, decremento , llamada a función , o coma , excepto que los operadores de conversión deben convertir tipos aritméticos a otros tipos aritméticos a menos que formen parte de un operando de sizeof , _Alignof (desde C11) (hasta C23) , alignof (desde C23) o typeof/typeof_unqual (desde C23)
- constantes enteras
- constantes flotantes
- constantes de enumeración
- constantes de carácter
-
sizeofoperadores cuyos operandos no son VLA (desde C99)
| (desde C11) |
|
(desde C23) |
-
- un puntero nulo
- lvalue que designa un objeto de duración de almacenamiento estática o un designador de función, convertido a un puntero ya sea
-
- usando el operador unario de dirección
- convirtiendo una constante entera a un puntero
- mediante conversión implícita conversión de array-a-puntero o función-a-puntero.
|
5)
una
constante con nombre
que es, un identificador que es
.
a una constante con nombre de tipo estructura o unión, incluso recursivamente.
6)
una
constante de literal compuesto
, que es
Una
constante de estructura o unión
es una constante con nombre o constante de literal compuesto con tipo estructura o unión, respectivamente. Si el operador de acceso a miembro
|
(desde C23) |
A diferencia de las expresiones constantes enteras, las expresiones de inicializador estático no requieren ser evaluadas en tiempo de compilación; el compilador tiene la libertad de convertir dichos inicializadores en código ejecutable que se invoca antes del inicio del programa.
static int i = 2 || 1 / 0; // inicializa i al valor 1
|
Esta sección está incompleta
Razón: otros mini-ejemplos |
El valor de un inicializador estático de punto flotante nunca es menos preciso que el valor de la misma expresión ejecutada en tiempo de ejecución, pero puede ser mejor.
Expresiones constantes de punto flotante
Las expresiones constantes aritméticas de tipos de punto flotante que no se utilizan en inicializadores estáticos siempre se evalúan como si fuera durante el tiempo de ejecución y se ven afectadas por el redondeo actual (si FENV_ACCESS está activado) y reportan errores como se especifica en math_errhandling .
void f(void) { #pragma STDC FENV_ACCESS ON static float x = 0.0 / 0.0; // inicializador estático: no genera una excepción float w[] = { 0.0 / 0.0 }; // genera una excepción float y = 0.0 / 0.0; // genera una excepción double z = 0.0 / 0.0; // genera una excepción }
Notas
Si una expresión se evalúa a un valor que no es representable por su tipo, no puede utilizarse como expresión constante.
Las implementaciones pueden aceptar otras formas de expresiones constantes. Sin embargo, estas expresiones constantes no se consideran expresiones constantes enteras, expresiones constantes aritméticas o expresiones constantes de dirección, y por lo tanto no pueden utilizarse en contextos que requieran estos tipos de expresiones constantes. Por ejemplo, int arr [ ( int ) + 1.0 ] ; declara un VLA.
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
-
- 6.6 Expresiones constantes (p: 95-96)
- Estándar C17 (ISO/IEC 9899:2018):
-
- 6.6 Expresiones constantes (p: 76-77)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 6.6 Expresiones constantes (p: 106-107)
- Estándar C99 (ISO/IEC 9899:1999):
-
- 6.6 Expresiones constantes (p: 95-96)
- Estándar C89/C90 (ISO/IEC 9899:1990):
-
- 3.4 EXPRESIONES CONSTANTES
Véase también
|
Documentación de C++
para
Expresiones constantes
|