variable una son qué que numéricas matematicas las expresión exponentes ejemplos definicion constantes constante computacional algoritmo algebraica alfanumericas c++ gcc c++11 language-lawyer constant-expression

c++ - una - variables y constantes



¿Gcc considera que los builtins de funciones de expresión no constantes son expresiones constantes? (2)

Por favor, vea la actualización para una mejor muestra del problema. El código original tiene una mezcla de problemas que enturbia la imagen :

Esta pregunta ¿Por qué puedo llamar a una función no constexpr dentro de una función constexpr? presentó el siguiente código

#include <stdio.h> constexpr int f() { return printf("a side effect!/n"); } int main() { char a[f()]; printf("%zd/n", sizeof a); }

Lo cual, como respondo, está mal formado, pero gcc 4.8.2 permite ( verlo en vivo ).

Pero, si usamos el -fno-builtin gcc genera un error ( verlo en vivo ):

error: call to non-constexpr function ''int printf(const char*, ...)'' return printf("a side effect!/n"); ^

así que seems que gcc considera que su versión integrada de printf es una expresión constante. gcc documenta los builtins aquí, pero no documenta este caso donde una función incorporada no constestable puede considerarse una expresión constante.

Si este es realmente el caso:

  • ¿Se permite que un compilador haga esto?
  • Si están permitidos, ¿no tienen que documentarlo para que sea conforme?
  • Puede considerarse una extensión, si es así, parece que esto requeriría una advertencia ya que el borrador de la sección estándar 1.4 C ++ , párrafo 8 del cumplimiento de la implementación, dice (el énfasis es mío ):

Una implementación conforme puede tener extensiones (incluidas funciones de biblioteca adicionales), siempre que no alteren el comportamiento de ningún programa bien formado. Se requieren implementaciones para diagnosticar programas que usan tales extensiones que están mal formadas de acuerdo con este Estándar Internacional . Sin embargo, una vez hecho esto, pueden compilar y ejecutar dichos programas.

Actualizar

Como Casey señala que hay algunas cosas en el problema original que lo convierten en un mal ejemplo. Un ejemplo simple sería usar std :: pow, que no es una función constexpr:

#include <cmath> #include <cstdio> constexpr double f() { return std::pow( 2.0, 2.0 ) ; } int main() { constexpr double x = f() ; printf( "%f/n", x ) ; }

Compila y construye sin advertencias o errores ( ver en vivo ) pero agregar -fno-builtin hace que genere un error ( verlo en vivo ). Nota: por qué las funciones matemáticas no son constexpr en C ++ 11 :

error: call to non-constexpr function ''double pow(double, double)'' return std::pow( 2.0, 2.0 ) ; ^


GCC no considera que f() sea ​​una expresión constante. Mire los diagnósticos para el primer programa de muestra que ha vinculado :

main.cpp: In function ''int main()'': main.cpp:10:19: warning: ISO C++ forbids variable length array ''a'' [-Wvla] char a[f()]; ^

El compilador no cree que f() sea ​​una expresión constante, sino que el programa está utilizando la extensión de GCC que permite matrices de longitud variable: matrices con tamaño no constante.

Si cambia el programa para forzar f() en una expresión constante:

int main() { constexpr int size = f(); char a[size]; printf("%zd/n", sizeof a); }

GCC informa un error :

main.cpp: In function ''int main()'': main.cpp:10:32: in constexpr expansion of ''f()'' main.cpp:5:41: error: ''printf(((const char*)"a side effect!/012"))'' is not a constant expression return printf("a side effect!/n"); ^


Sí, gcc está considerando algunas funciones integradas como constexpr incluso si el estándar no las marca explícitamente como tales. Podemos encontrar la discusión que pertenece específicamente a la función matemática que se encuentra en cmath en el informe de error gcc [C ++ 0x] sinh vs asinh vs constexpr que dice:

LWG 2013 parece permitirle a GCC considerar estas funciones como constexpr. Entonces, arreglado para 4.7

que se refiere a la edición de LWG 2013, cuya resolución original propuesta era agregar lo siguiente a la sección 17.6.5.6 [funciones de constexto] ( énfasis mío en el futuro ):

[...] Además, una implementación puede declarar que cualquier función es concordante si la definición de esa función satisface las restricciones necesarias [...]

pero después de C ++ 11 la resolución se revirtió y la resolución final terminó como:

[...] Una implementación no declarará ninguna firma de función de biblioteca estándar como constexpr, excepto aquellas en las que se requiera explícitamente. [..]

Así que esto es actualmente ( en C ++ 14 ) una extensión explícitamente no conforme y hasta donde puedo decir que esto no era conforme en C ++ 11 ya que altera el comportamiento observable y por lo tanto no se permitiría a través del regla .

Jonathan Wakely señala una discusión de la lista de correo libstdc++ : PR libstdc ++ / 49813 revisited: constexpr on functions (and builtins) donde se discutió la reapertura del informe de error mencionado anteriormente debido a los problemas expuestos anteriormente:

Creo que deberíamos volver a abrir el error a la luz de la resolución real de LWG 2013 (agregar constexpr está prohibido).

El FE no debe tratar las construcciones internas como constexpr en modo de conformidad estricta.

Deberíamos eliminar _GLIBCXX_CONSTEXPR de <cmath> por completo o hacerlo condicional en __STRICT_ANSI__.