|
|
|
|
|
by simiones
1168 days ago
|
|
That is a complete misunderstanding. A constexpr function can very well take an input, and it can invoke UB based on the runtime value of that input. What the standard prohibits is compile-time evaluation of an expression which invokes UB. So, if you actually call your function at compile-time with a constexpr value that ends up invoking UB in the function (say, an integer overflow), THEN the standard mandates that the compiler throw an error rather than compiling some random value in. For example: constexpr void foo(int x) {
std::cout << 1024 * 1024 * 1024 * x;
}
int main() {
static_assert(foo(100)); // will fail because computing 1024 * 1024 * 100 is signed integer overflow, which is UB
foo(100); // invokes UB at runtime; in practice, will perhaps print some overflowed value
}
Edit: I should also add that you can very well invoke UB in a constexpr expression if it is standard library UB and not core language UB (e.g. if you try to pop() from an empty std::vector). |
|
No, it cannot. It is not constant if it does that. As such, it cannot be used in in any context that requires a constant expression. It explicitly says the operations in a constexpr may not produce undefined behavior.
That isn't "may not produce undefined behavior except if you pass the wrong values at runtime or don't evaluate it". It says: "An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (6.8.1), would evaluate one of the following expressions:
…
an operation that would have undefined behavior "
In your case, the evaluation would evaluate (at runtime) an operation that would have undefined behavior.
It is true that where you do not require a constant expression, it does not require it be constexpr at all, but the question is whether an expression that produces undefined behavior is constexpr is "no".
The standard even clarified this to say that foo is simply considered non-constant in your example (IE it's not constexpr ).
IE see defect report 695
"The consensus of the CWG was that an expression like 1/0 should simply be considered non-constant; any diagnostic would result from the use of the expression in a context requiring a constant expression. "
In your example, foo is non-constant as used. It is not constexpr.