una todas parametros las initialize funciones funcion ejemplos declara con como c++ language-lawyer c++17 constexpr

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 constexpr cumplirá 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 constexpr o 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.