todas - static function c++
Modificar una variable global en una función constexpr en C++ 17 (2)
¿Qué compilador es correcto?
Clang tiene razón.
La definición de una función constexpr según dcl.constexpr/3
La definición de una función
constexprcumplirá los siguientes requisitos:
(3.1) su tipo de devolución será un tipo literal;
(3.2) cada uno de sus tipos de parámetros debe ser de tipo literal;
(3.3) su cuerpo-función será= delete,= default, o una declaración compuesta que no contenga:
(3.3.1) una definición de asm,
(3.3.2) una declaración goto,
(3.3.3) una etiqueta identificadora,
(3.3.4) un try-block o
(3.3.5) una definición de una variable de tipo no literal o de duración de almacenamiento estático o de subprocesos o para la que no se realiza ninguna inicialización.
También según dcl.constexpr/5 :
Para una función
constexpro constructor constexpr que no está ni en default ni en una plantilla, si no existen valores de argumento tales que una invocación de la función o constructor podría ser una subexpresión evaluada de una expresión constante central,
Foo(true) podría evaluarse a una expresión constante central (es decir, 1 ).
Además, Foo(false) podría ser pero no se requiere que sea evaluado constantemente.
CONCLUSIÓN
Por lo tanto, un 86327 en GCC.
Muchas gracias a @Barry, @aschepler y @BenVoigt por ayudarme con esta respuesta. En C ++ 17, ¿se le permite modificar variables globales en una función constexpr ?
#include <iostream>
int global = 0;
constexpr int Foo(bool arg) {
if (arg) {
return 1;
}
return global++;
}
int main() {
std::cout << global;
Foo(true);
std::cout << global;
Foo(false);
std::cout << global;
}
No esperaría que pudieras, pero clang 6 lo permite: https://godbolt.org/g/UB8iK2
GCC, sin embargo, no: https://godbolt.org/g/ykAJMA
¿Qué compilador es correcto?
Añadiré que dcl.constexpr / 5 también requiere:
Para una función constexpr o constructor constexpr que no está ni predeterminado ni una plantilla, si no existen valores de argumento tales que una invocación de la función o el constructor podría ser una subexpresión evaluada de una expresión constante central o, para un constructor, un inicializador constante para algún objeto ([basic.start.static]), el programa está mal formado, no se requiere diagnóstico.
Como deiberadamente escribió la función para que Foo(true) evalúe una expresión constante central, Foo(false) no es necesario para.