В <cinttypes>
, поскольку С++ 11, следующие две перегрузки:
std::intmax_t abs( std::intmax_t n );
std::intmax_t imaxabs( std::intmax_t n );
Почему не эти две функции constexpr
?
В <cinttypes>
, поскольку С++ 11, следующие две перегрузки:
std::intmax_t abs( std::intmax_t n );
std::intmax_t imaxabs( std::intmax_t n );
Почему не эти две функции constexpr
?
Я не могу объяснить, почему abs
не может быть constexpr
и, по-видимому, не может gcc
. Когда я использую gcc 4.9.2
с этой программой:
#include <cstdlib>
#include <cinttypes>
#include <cassert>
constexpr intmax_t abs3 = std::abs(3);
constexpr intmax_t absneg3 = std::abs(-3);
int main()
{
assert(abs3 == absneg3);
}
он компилируется и запускается до завершения без предупреждений или ошибок. Вы можете попробовать здесь. Однако clang++
(версия 3.5.0) генерирует ошибку времени компиляции:
abs.cpp: 6: 20: ошибка: constexpr переменная 'abs3' должна быть инициализирована константным выражением.
Я думаю, что clang++
действительно получает это прямо здесь, потому что в разделе 27.9.2 [c.files] стандарта 2011 года говорится:
Содержимое заголовка совпадает с заголовком стандартной библиотеки C со следующими изменениями:
- заголовок содержит заголовок вместо, и
- тогда и только тогда, когда тип intmax_t обозначает расширенный целочисленный тип (3.9.1), следующая функция добавляются подписи:
intmax_t abs (intmax_t);
imaxdiv_t div (intmax_t, intmax_t);
который должен иметь ту же семантику, что и сигнатуры функции intmax_t imaxabs (intmax_t) и imaxdiv_t imaxdiv (intmax_t, intmax_t) соответственно.
В текущий рабочий проект стандарта С++, как и в опубликованной версии 2014 года, говорится в разделе 17.6.5.6 [constexpr.functions ]:
Этот стандарт явно требует, чтобы определенные стандартные библиотечные функции были constexpr (7.1.5). Реализация не должна объявлять какую-либо стандартную подпись функции библиотеки как constexpr, за исключением тех, где она явно требуется.
Итак, на данный момент результат состоит в том, что эти функции по-прежнему не соответствуют constexpr
в соответствии со стандартом (который вы знали), но они могут быть, как продемонстрировано компилятором gcc
.
Простое объяснение, вероятно, в том, что никто не прошел через каждую функцию, указанную как часть стандартной библиотеки, и обновил запись, чтобы сделать ее constexpr
.
Обновление стандарта - это процесс, включающий человеческие усилия по предложению изменений и их рассмотрение и принятие. А это означает, что при добавлении новой функции - и constexpr
- это новая функция, а не все остальное автоматически обновляется для использования этой функции. Этот конкретный случай вполне может быть обновлен в будущей эволюции стандарта - если некоторые люди возьмут на себя часто неблагодарную задачу предложить набор изменений, некоторые другие люди возьмут на себя задачу его рассмотрения и убедят тех, кто имеет право голоса на комитет, чтобы принять его.