clang 3.4
не компилирует этот код, так как sum(get_str())
не constexpr и, насколько я могу сказать clang
правильно здесь, эта линия (see it live):
constexpr int s = sum(get_str());
генерирует следующее сообщение об ошибке:
error: constexpr variable 's' must be initialized by a constant expression
constexpr int s = sum(get_str());
^ ~~~~~~~~~~~~~~
note: read of temporary whose lifetime has ended
return str[0] + str[1] + str[2] + str[3]
^
Недействительный constexpr
по двум причинам. Это вызывает неопределенное поведение, и это explicitly disallowed in a constant expression, обобщать the draft C++ standard раздел 5.19
говорит:
A conditional-expression e is a core constant expression unless the evaluation of e,
и содержит следующую пулю:
an operation that would have undefined behavior
который доступ вне его жизни будет. Мы знаем, что время жизни временно не распространяется в данном случае из раздела 12.2
Временных объектов который говорит:
The second context is when a reference is bound to a temporary.117 The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except
и включает в себя следующую пулю:
The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
Так что, хотя это действительно так, что a константное выражение не может быть оценено при переводе, мы имеем примечание в разделе 5.19
Константные выражения, которые упоминают это (курсив мой идти вперед):
Note: Constant expressions can be evaluated during translation.—end note ]
Даже если это было гарантировано мы все еще не будет позволено вызвать неопределенное поведение.
Второй вопрос заключается в том, что constexpr ссылки должны быть либо к объектам статической продолжительности хранения или функций, cppreference упоминает об этом в своем core constant expression section:
Reference constant expression is an lvalue core constant expression that designates an object with static storage duration or a function
и, насколько я могу сказать, что это рассматривается в разделе 5.19
Постоянные выражения пункт который говорит:
each non-static data member of reference type refers to an object with static storage duration or to a function,
Вы можете использовать 'станд :: массив ', чтобы вернуть статический массив constexpr по значению, вместо того, чтобы возвращать ссылку. –
@MikaelPersson Спасибо, я попытался использовать std :: array в какой-то момент, но мой полный код выполняет некоторые странные вещи, которые требуют преобразования времени компиляции в const char *, и я не мог сделать & arr [0] в константе выражение. – Xeno