¿Está gcc considerando que las funciones integradas de expresión no constante son expresiones constantes?

Consulte la actualización para obtener 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);
}

Que como respondo esmal formado perogcc 4.8.2 lo permite (verlo en vivo)

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

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

por lo queseems esegcc está considerando su versión incorporada deprintf ser una expresión constantegcc documentos incorporados aquí pero no documenta este caso en el que una función incorporada no constexpr puede considerarse una expresión constante.

Si este es realmente el caso:

¿Se le permite a un compilador hacer esto?Si se les permite, ¿no tienen que documentarlo para que sea conforme?¿Puede considerarse esto una extensión? Si es así, parece que esto requeriría una advertencia ya queBorrador de C ++ estándar sección1.4 Cumplimiento de implementación$28verlo en vivo29$énfasis 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 esta Norma Internacional. Una vez hecho esto, sin embargo, pueden compilar y ejecutar dichos programas.

Actualizar

Como señala Casey, hay algunas cosas en el problema original que lo convierten en un mal ejemplo. Un ejemplo simple sería usarstd :: 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 ni errores (verlo en vivo) pero agregando-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 ) ;
                               ^

Respuestas a la pregunta(2)

Su respuesta a la pregunta