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 ) ;
^