Ответ 1
Программа плохо сформирована и не требует диагностики в соответствии с С++ 11 черновик проекта 7.1.5
Параметр спецификатора constexpr 5, в котором говорится:
Для функции constexpr, если значения аргументов функции не существуют что подстановка функции вызовет постоянство выражение (5.19), программа плохо сформирована; не требуется диагностика.
и предоставляет следующий пример:
constexpr int f(bool b)
{ return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required
и раздел 5.19
в абзаце 2 говорится:
Условное выражение является выражением постоянной константы, если оно включает одно из следующего в качестве потенциально оцениваемого подвыражения [...]
и включает в себя:
- вызов функции, отличной от конструктора constexpr для литеральный класс или функция constexpr [Примечание: разрешение перегрузки (13.3) применяется как обычно - примечание];
Мы бы предпочли диагностику в этом случае, это может быть просто недосмотр, у меня есть отчет об ошибке для аналогичной ситуации, когда gcc
не вызывает ошибку, но нам бы это понравилось: Является ли компилятор разрешенным лишением в том, что он считает undefined поведение в постоянном выражении?.
Обновить
Использование флага -fno-builtin
приведет к тому, что gcc
создаст следующую ошибку:
error: call to non-constexpr function 'int printf(const char*, ...)'
return printf("a side effect!\n");
^
Итак, gcc
считает, что это плохо сформированное, оно просто игнорирует его, когда использует встроенную версию printf
.
Хотя несколько непоследовательно использование -pedantic
вызывает следующее предупреждение:
warning: ISO C++ forbids variable length array 'a' [-Wvla]
char a[f()];
^
Обратите внимание, что с помощью f()
для инициализации переменной constexpr:
constexpr int x = f() ;
создает ошибку:
error: 'printf(((const char*)"a side effect!\012"))' is not a constant expression
Обратите внимание, что дополнительно в более общем случае компилятору не разрешено отмечать стандартные библиотечные функции как constexpr если явно не разрешено стандартом.