GCC рассматривает встроенные функции непостоянных выражений как постоянные выражения

Пожалуйста, смотрите обновление для лучшего примера проблемы. Оригинальный код имеет множество проблем, которые запутывают картину:

Этот вопросПочему я могу вызвать функцию не-constexpr внутри функции constexpr? представил следующий код

#include <stdio.h>

constexpr int f()
{
    return printf("a side effect!\n");
}

int main()
{
    char a[f()];
    printf("%zd\n", sizeof a);
}

Который, как я отвечаюплохо формируется ноgcc 4.8.2 позволяет это (увидеть это в прямом эфире).

Но если мы используем-fno-builtin флагgcc выдает ошибку (увидеть это в прямом эфире):

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

так чтоseems тотgcc рассматривает его встроенную версиюprintf быть постоянным выражением.gcc документы встроенные здесь но не документирует этот случай, когда встроенную функцию non-constexpr можно считать константным выражением.

Если это действительно так:

Разрешено ли это делать компилятору?Если они разрешены, не должны ли они документировать это, чтобы соответствовать?Может ли это считаться расширением, если так, то кажется, что для этого потребуется предупреждение, посколькуПроект стандарта C ++ раздел1.4 Соответствие реализации параграф8 говорит (акцент мой):

Соответствующая реализация может иметь расширения (включая дополнительные библиотечные функции), при условии, что они не изменяют поведение любой правильно сформированной программы.Внедрения требуются для диагностики программ, использующих такие расширения, которые неправильно сформированы в соответствии с настоящим международным стандартом., Сделав это, однако, они могут компилировать и выполнять такие программы.

Обновить

Как указывает Кейси, в исходной задаче происходит несколько вещей, которые делают ее плохим примером. Простой пример будет использоватьстанд :: пау которая не является функцией 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 ) ;
}

Компилирует и строит без предупреждений или ошибок (увидеть это в прямом эфире) но добавляю-fno-builtin заставляет выдавать ошибку (увидеть это в прямом эфире). Замечания:почему математические функции не являются constexpr в C ++ 11:

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

Ответы на вопрос(2)

Ваш ответ на вопрос