См. обновление для лучшего примера проблемы. В исходном коде есть множество проблем, которые мешают изображению:
Этот вопрос Почему я могу вызвать функцию non-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
здесь встроены документы, но не документирует этот случай, когда встроенное значение функции, отличной от constexpr, может считаться константным выражением.
Если это действительно так:
- Разрешено ли компилятору сделать это?
- Если они разрешены, им не нужно документировать, чтобы они были совместимыми?
- Можно ли это считать расширением, если это так, похоже, это потребует предупреждения как С++ draft standard раздел
1.4
В соответствии с пунктом 8 выполнения, в котором говорится (подчеркивает мой):
Соответствующая реализация может иметь расширения (включая дополнительные функции библиотеки) при условии, что они не изменят поведение какой-либо хорошо сформированной программы. Реализации необходимы для диагностики программ, которые используют такие расширения, которые плохо сформированы в соответствии с этим международным стандартом. Однако, сделав это, они могут компилировать и выполнять такие программы.
Обновить
Как указывает Кейси, в исходной проблеме происходит несколько вещей, которые делают ее плохим примером. Простым примером будет использование std:: pow, который не является функцией 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 в С++ 11:
error: call to non-constexpr function 'double pow(double, double)'
return std::pow( 2.0, 2.0 ) ;
^