O gcc está considerando expressões internas constantes de funções de expressão não constante como expressões constantes

Consulte a atualização para obter uma amostra melhor do problema. O código original tem uma mistura de problemas que atrapalham a imagem:

Essa questãoPor que posso chamar uma função não constexpr dentro de uma função constexpr? apresentou o seguinte 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 eu respondo, émal formado masgcc 4.8.2 permite (veja ao vivo)

Mas, se usarmos o-fno-builtin bandeiragcc gera um erro (veja ao vivo):

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

entãoseems estegcc está considerando sua versão interna doprintf para ser uma expressão constante.gcc documentos embutidos aqui mas não documenta esse caso em que um builtin de uma função não constexpr pode ser considerada uma expressão constante.

Se este é realmente o caso:

Um compilador está autorizado a fazer isso?Se eles são permitidos, eles não precisam documentá-lo para estar em conformidade?Isso pode ser considerado uma extensão? Nesse caso, parece que isso exigiria um aviso, pois oPadrão de rascunho em C ++ seção1.4 Conformidade da implementação$28veja ao vivo29$ênfase minha):

Uma implementação em conformidade pode ter extensões (incluindo funções adicionais da biblioteca), desde que não alterem o comportamento de nenhum programa bem formado.São necessárias implementações para diagnosticar programas que usam extensões mal formadas de acordo com esta Norma.. Tendo feito isso, no entanto, eles podem compilar e executar esses programas.

Atualizar

Como Casey aponta, há algumas coisas acontecendo no problema original que o tornam um exemplo ruim. Um exemplo simples seria usarstd :: pow que não é uma função 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 e cria sem avisos ou erro (veja ao vivo) mas adicionando-fno-builtin faz com que gere um erro (veja ao vivo) Nota:por que as funções matemáticas não são constexpr no C ++ 11:

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

questionAnswers(2)

yourAnswerToTheQuestion