Espacios de nombres
Variantes
Acciones

Expresiones

De cppreference.com
< cpp‎ | language
 
 
 
 

Un expresión es una secuencia de operadores y sus operandos, que especifican un cálculo.

La evaluación de expresiones puede producir un resultado (p. ej., la evaluación de 2+2 produce el resultado 4) y puede generar otros efectos (p. ej., la evaluación de std::printf("%d",4) imprime en la salida estándar el carácter '4').

Cada expresión de C++ se caracteriza por dos propiedades independientes: un tipo y una categoría de valor.

Contenido

[editar] General

  • Las categorías de valor (l-valor, r-valor, gl-valor, pr-valor, x-valor) clasifican las expresiones según sus valores.
  • El orden de evaluación de los argumentos y subexpresiones especifican el orden que se obtienen los resultados intermedios.

[editar] Operadores

Operadores comunes
Asignación Incremento/decremento Aritméticos Lógicos Comparación Acceso a miembro Otros

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
? :

Operadores especiales

static_cast Convierte de un tipo a otro tipo relacionado
dynamic_cast Convierte dentro de jerarquías de herencia
const_cast Añade o suprime los calificadores const/volatile
reinterpret_cast Convierte un tipo a un tipo no relacionado
conversión estilo C Convierte un tipo a otro mediante una mezcla de static_cast, const_cast, y reinterpret_cast
new Crea objetos con duración de almacenamiento dinámica
delete Destruye objetos previamente creados por la expresión new y libera el área de memoria obtenida
sizeof Consulta el tamaño de un tipo
sizeof... Consulta el tamaño de un paquete de parámetros (desde C++11)
typeid Consulta la información de un tipo
noexcept Comprueba si una expresión puede lanzar una excepción (desde C++11)
alignof Consulta requisitos de alineación de un tipo (desde C++11)

[editar] Conversiones

[editar] Asignación de memoria

[editar] Otros

[editar] Expresiones primarias

Los operandos de cualquier operador puede ser otras expresiones o expresiones primarias (p. ej., en 1+2*3, los operandos de operator+ son la subexpresión 2*3 y la expresión primaria 1).

Las expresiones primarias son una de las siguientes:

(desde C++26)
(desde C++11)
(desde C++17)
(desde C++20)

También se clasifica como expresión primaria cualquier expresión entre paréntesis: esto garantiza que los paréntesis tienen mayor precedencia que cualquier operador. Los paréntesis conservan el valor, tipo, y la categoría de valor.

[editar] Literales

Los literales son tókenes de un programa C++ que representan valores contantes embebidos en el código fuente.

  • char o wchar_t,
  • char16_t o char32_t,
(desde C++11)
  • char8_t.
(desde C++20)
  • const char[] o const char16_t[],
  • const char16_t[] o const char32_t[],
(desde C++11)
  • const char8_t[].
(desde C++20)
(desde C++11)

[editar] Expresiones completas

Una expresión constituyente se define de la siguiente manera:

  • La expresión constituyente de una expresión es esa expresión.
  • Las expresiones constituyentes de una lista-de-inicio-entre-llaves o de una lista de expresiones (posiblemente entre paréntesis) son las expresiones constituyentes de los elementos de la lista respectiva.
  • Las expresiones constituyentes de un inicializador-entre-llaves-o-igual de la forma = cláusula-inicializadora son las expresiones constituyentes de la cláusula-inicializadora.
int num1 = 0;
num1 += 1; // Caso 1: la expresión constituyente de `num += 1` es `num += 1`
 
int arr2[2] = {2, 22} // Caso 2: las expresiones constituyentes
                      //         de `{2, 22}` son `2` y `22`
                      // Caso 3: las expresiones constituyentes de ` = {2, 22}`
                      //         son las expresiones constituyentes de `{2, 22}`
                      //         (es decir, también `2` y `22`)

Las subexpresiones inmediatas de una expresión E son

  • las expresiones constituyentes de los operandos de E,
(desde C++14)
  • si E es una expresión lambda, la inicialización de las entidades capturadas por la copia y las expresiones constituyentes del inicializador de las capturas,
(desde C++11)
  • cualquier llamada a función que E invoque implícitamente, o
  • si E es una llamada a función o invoca implícitamente una función, las expresiones constituyentes de cada argumento por defecto utilizado en la llamada.

Una subexpresión de una expresión E es una subexpresión inmediata de E o una subexpresión de una subexpresión inmediata de E. Ten en cuenta que las expresiones que aparecen en el ‘cuerpo de la función’ de las expresiones lambda no son subexpresiones de la expresión lambda. (desde C++11)

Una expresión completa es

  • un declarador de una declaración simple o un inicializador de miembro, incluidas las expresiones constituyentes del inicializador,
  • una invocación de un destructor generado al final del tiempo de vida de un objeto que no sea un objeto temporal cuya tiempo de vida no se haya extendido, o
  • una expresión que no sea una subexpresión de otra expresión y que no sea parte de una expresión completa.

Si se define una construcción del lenguaje para producir una llamada implícita a una función, el uso de la construcción del lenguaje se considera una expresión para efectos de esta definición. Las conversiones aplicadas al resultado de una expresión para satisfacer los requisitos de la construcción del lenguaje en la que aparece la expresión también se consideran parte de la expresión completa.

Para un inicializador, realizar la inicialización de la entidad (incluida la evaluación de inicializadores de miembros por defecto de un agregado) (desde C++14) también se considera parte de la expresión completa.

[editar] Expresiones potencialmente evaluadas

Una expresión es potencialmente evaluada a menos que

  • sea el operando del operador sizeof, o
  • sea el operando del operador typeid y no designe un valor l-valor de tipo clase polimórfica.
(hasta C++11)

Los siguientes operandos son operandos no evaluados, es decir, no se evalúan:

  • expresiones a las que se aplica el operador typeid, excepto los gl-valores de los tipos clase polimórfica
  • expresiones que son operandos del operador sizeof
  • operandos del operador noexcept
  • operandos del especificador decltype
(desde C++20)

Una expresión es potencialmente evaluada a menos que

  • sea un operando no evaluado, o
  • sea una subexpresión de un operando no evaluado.
(desde C++11)

Las expresiones potencialmente evaluadas son de uso ODR.

[editar] Expresiones de valor descartado

Una expresión de valor descartado es una expresión que se utiliza solo por sus efectos secundarios. El valor calculado de la expresión se descarta. Dichas expresiones incluyen la expresión completa de cualquier instrucción de expresión, el operando a la izquierda del operador coma integrado, o el operando de una expresión de conversión que convierte al tipo void.

Las conversiones array a puntero y función a puntero nunca se aplican al valor calculado por una expresión de valor descartado. La conversión de l-valor a r-valor, sin embargo, se aplica, pero solo si la expresión es un gl-valor calificado volatile y tiene una de las formas siguientes (requiere un significado integrado, posiblemente entre paréntesis):

  • expresión id,
  • expresión de subíndice de array,
  • expresión de acceso a miembro de clase,
  • indirección,
  • operación de puntero a miembro,
  • expresión condicional donde tanto el segundo como el tercer operando son una de estas expresiones,
  • expresión de coma donde el operando derecho es una de estas expresiones.

Si la expresión es un pr-valor no void (después de cualquier conversión de l-valor a r-valor que podría haber tenido lugar), la materialización temporal ocurre.

[[nodiscard]].

(desde C++17)

Equivalencia de expresiones

Varias expresiones e1, e2, ..., eN son de expresión equivalente si se cumplen todas las condiciones siguientes:

  1. tienen los mismos efectos;
  2. o todas son subexpresión constante o ninguna lo es;
  3. o todas son noexcept o ninguna lo es.

e1 es de expresión equivalente a e2 si y solo si e1 y e2 son de expresión equivalente (lo que significa que e2 también es de expresión equivalente e1).

(desde C++20)

[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 1054 C++98 Asignar un valor a una variable volátil podría
resultar en una lectura innecesaria debido a la conversión de
l-valor a r-valor aplicada al resultado de la asignación.
Introducir expresiones de valor descartado
y excluir este caso de la lista
de casos que requieren la conversión.
CWG 1343 C++98 La secuencia de llamadas al destructor en
la inicialización de agregado estaba subespecificada.
Las expresiones completas en la inicialización de agregado
están bien especificadas.
CWG 1383 C++98 La lista de expresiones donde la conversión de l-valor a r-valor
se aplica a expresiones de valor descartado
también cubría los operadores sobrecargados.
Solo cubre los operadores
con significado integrado.
CWG 1576 C++11 Las conversiones de l-valor a r-valor no se aplicaban
a expresiones xvalue volátiles de valor descartado.
Se aplican a la conversión
en este caso.
CWG 2249 C++98 Los identificadores que se deben declarar en los declaradores
no eran expresiones id.
Sí lo son.
CWG 2431 C++11 las invocaciones de los destructores de temporales que
están ligados a referencias no eran expresiones completas.
Lo son.

[editar] Véase también

Documentación de C para Expresiones