volatiles volatil que porque palabra oraciones mas con agua acetona c++ c++11 gcc clang language-lawyer

c++ - palabra - porque la acetona es mas volatil que el agua



¿Se puede combinar constexpr con volátil? (2)

Citando N4140 [dcl.constexpr] / 9:

Un especificador constexpr utilizado en una declaración de objeto declara que el objeto es const . Dicho objeto tendrá un tipo literal y se inicializará.

El tipo literal se define en [tipos de base] / 10:

Un tipo es un tipo literal si es:

(10.1) - void ; o

(10.2) - un tipo escalar; o

(10.3) - un tipo de referencia; o

(10.4) - una matriz de tipo literal; o

(10.5) - un tipo de clase (Cláusula 9) que tiene todas las siguientes propiedades:

(10.5.1) - tiene un destructor trivial,

(10.5.2): es un tipo agregado (8.5.1) o tiene al menos un constructor constexpr o plantilla de constructor que no es un constructor de copia o movimiento, y

(10.5.3) - todos sus miembros de datos no estáticos y clases base son de tipos literales no volátiles.

El tipo escalar está en el párrafo 9:

Los tipos aritméticos (3.9.1), los tipos de enumeración, los tipos de puntero, los tipos de puntero a los miembros (3.9.2), std::nullptr_t y las versiones calificadas con std::nullptr_t de estos tipos (3.9.3) se denominan colectivamente tipos escalares .

int es aritmética, por lo que volatile int es un tipo escalar y, por lo tanto, un tipo literal. constexpr volatile int i = 5; Es pues una declaración bien formada.

Curiosamente, una expresión que evalúa i no puede ser una expresión constante de núcleo, ya que aplica una conversión de valor de rvalor a un valor de tipo volátil ([expr.const] / 2). En consecuencia, las expresiones que evalúan i no son expresiones constantes integrales ni expresiones constantes . No estoy seguro de que el constexpr en esa declaración tenga algún efecto más allá de hacer que implícitamente const , y (asentir a @T.C. ) requiere que su inicializador sea una expresión constante.

He reportado esto como GCC bug 65327 , veremos lo que la gente de GCC tiene que decir.

2015-03-16 Actualización: Error corregido para GCC 5.

El siguiente fragmento de código funciona bien en Clang 3.5 pero no en GCC 4.9.2:

int main() { constexpr volatile int i = 5; }

con error:

error: tanto ''volatile'' como ''constexpr'' no se pueden usar aquí

Si inspecciono el ensamblaje que genera Clang, muestra 5 como se esperaba:

movl $5, -4(%rsp)

En GCC, constexpr int i = 5 se optimiza, pero la volatile int i = 5 también muestra 5 en el ensamblaje. volatile const int i = 5 compila en ambos compiladores. No es un concepto extraño para que algo sea volátil y constante al mismo tiempo.

¿Qué compilador es correcto para los estándares?


Sí, esto es válido, hubo un informe de defectos 1688: variables constexpr volátiles que se archivaron para esto, diciendo:

No parece haber un idioma en la redacción actual que indique que constexpr no se puede aplicar a una variable de tipo calificado como volátil. Además, la redacción en 5.19 [expr.const] párrafo 2 que se refiere a "un objeto no volátil definido con constexpr" podría llevar a inferir que la combinación está permitida pero que tal variable no puede aparecer en una expresión constante. ¿Cuál es la intención?

fue rechazado por no ser un defecto ( NAD ), la respuesta y el razonamiento fue:

La combinación está permitida intencionalmente y podría usarse en algunas circunstancias para forzar una inicialización constante.

Como el DR señala que una variable de este tipo no es utilizable en una expresión constante :

constexpr volatile int i = 5; constexpr int y = i ; // Not valid since i is volatile

La sección [expr.const] / 2 incluye todos los casos que hacen que una expresión condicional no sea una expresión constante central, que incluye:

una conversión de lvalue a rvalue (4.1) a menos que se aplique a

y toda la excepción requiere:

[...] que se refiere a un objeto [...] no volátil [...]